#!/usr/bin/perl -w use strict; use Benchmark qw(cmpthese); use Data::Dumper; sub xform { map {$_->[0]} sort { $a->[1] <=> $b->[1]} map {[$_, rand(1)]} @_; } sub slice { my @random; push @random, rand 1 for 0 .. $#_; @_[ sort { $random[$a] <=> $random[$b] } 0 .. $#_ ]; } sub shufl { $a = $_ + rand @_ - $_ and @_[$_, $a] = @_[$a, $_] for (0..$#_); return @_; } sub qshuf { my @sorted = sort { .5 <=> rand(1) } @_; } my @array = 1 .. 1000; cmpthese(10000, { slice => sub { slice @array }, xform => sub { xform @array }, shufl => sub { shufl @array }, qshuf => sub { qshuf @array }, }); my (%buckets, %d, @temp);; my @set = qw(A B C D); for (1 .. 100_000 ) { $buckets{"@{[slice @temp=@set]}"}{slice}++; $buckets{"@{[xform @temp=@set]}"}{xform}++; $buckets{"@{[shufl @temp=@set]}"}{shufl}++; $buckets{"@{[qshuf @temp=@set]}"}{qshuf}++; } print "\npermutation | slice | xform | shufl | qshuf \n"; print "--------------------------------------------------\n"; for my $key (sort keys %buckets) { printf "%8.8s: | %4d | %4d | %4d | %4d\n", $key, $buckets{$key}{slice}, $buckets{$key}{xform}, $buckets{$key}{shufl}, $buckets{$key}{qshuf}; $d{slice}{Ex} += $buckets{$key}{slice}; $d{slice}{Ex2} += $buckets{$key}{slice}**2; $d{xform}{Ex} += $buckets{$key}{xform}; $d{xform}{Ex2} += $buckets{$key}{xform}**2; $d{shufl}{Ex} += $buckets{$key}{shufl}; $d{shufl}{Ex2} += $buckets{$key}{shufl}**2; $d{qshuf}{Ex} += $buckets{$key}{qshuf}; $d{qshuf}{Ex2} += $buckets{$key}{qshuf}**2; } print "---------------------------------------------------\n"; printf "Std. Dev. | %0.3f | %0.3f | %0.3f | %0.3f\n", sqrt( ($d{slice}{Ex2} - ($d{slice}{Ex}**2/24))/23 ), sqrt( ($d{xform}{Ex2} - ($d{xform}{Ex}**2/24))/23 ), sqrt( ($d{shufl}{Ex2} - ($d{shufl}{Ex}**2/24))/23 ), sqrt( ($d{qshuf}{Ex2} - ($d{qshuf}{Ex}**2/24))/23 ); __END__ P:\test>c:\perl561\bin\perl5.6.1.exe 200083.pl Benchmark: timing 10000 iterations of qshuf, shufl, slice, xform... qshuf: 24 wallclock secs (22.86 usr + 0.01 sys = 22.88 CPU) @ 437.16/s (n=10000) shufl: 15 wallclock secs (14.78 usr + 0.00 sys = 14.78 CPU) @ 676.54/s (n=10000) slice: 38 wallclock secs (36.69 usr + 0.00 sys = 36.69 CPU) @ 272.57/s (n=10000) xform: 56 wallclock secs (55.39 usr + 0.00 sys = 55.39 CPU) @ 180.53/s (n=10000) Rate xform slice qshuf shufl xform 181/s -- -34% -59% -73% slice 273/s 51% -- -38% -60% qshuf 437/s 142% 60% -- -35% shufl 677/s 275% 148% 55% -- permutation | slice | xform | shufl | qshuf -------------------------------------------------- A B C D: | 4168 | 4266 | 4233 | 12486 A B D C: | 4072 | 4170 | 4091 | 6165 A C B D: | 4232 | 4185 | 4159 | 6231 A C D B: | 4205 | 4169 | 4191 | 3151 A D B C: | 4285 | 4211 | 4031 | 3081 A D C B: | 4219 | 4124 | 4197 | 1549 B A C D: | 4204 | 4160 | 4248 | 12385 B A D C: | 4132 | 4164 | 4133 | 6241 B C A D: | 4147 | 4138 | 4346 | 6281 B C D A: | 4242 | 4166 | 4022 | 3086 B D A C: | 4174 | 4114 | 4075 | 3131 B D C A: | 4175 | 4173 | 4103 | 1556 C A B D: | 4236 | 4306 | 4194 | 6163 C A D B: | 4158 | 4236 | 4146 | 3068 C B A D: | 4095 | 4126 | 4278 | 6406 C B D A: | 4160 | 4092 | 4245 | 3104 C D A B: | 4141 | 4181 | 4150 | 1614 C D B A: | 4097 | 4175 | 4163 | 1620 D A B C: | 4167 | 4220 | 4246 | 3147 D A C B: | 4220 | 4057 | 4138 | 1593 D B A C: | 4095 | 4194 | 4192 | 3184 D B C A: | 4170 | 4131 | 4179 | 1636 D C A B: | 4054 | 4072 | 4159 | 1487 D C B A: | 4152 | 4170 | 4081 | 1635 --------------------------------------------------- Std. Dev. | 57.747 | 57.211 | 77.656 | 3126.744 #### #!/usr/bin/perl -w use strict; use List::Util qw[ shuffle ]; use Benchmark qw(cmpthese); use Data::Dumper; sub xform { map {$_->[0]} sort { $a->[1] <=> $b->[1]} map {[$_, rand(1)]} @_; } sub slice { my @random; push @random, rand 1 for 0 .. $#_; @_[ sort { $random[$a] <=> $random[$b] } 0 .. $#_ ]; } sub shufl { $a = $_ + rand @_ - $_ and @_[$_, $a] = @_[$a, $_] for (0..$#_); return @_; } sub qshuf { my @sorted = sort { .5 <=> rand(1) } @_; return @sorted; } sub Ushuf { my @shuffled = shuffle @_; return @shuffled; } my @array = 1 .. 1000; cmpthese(10000, { slice => sub { slice @array }, xform => sub { xform @array }, shufl => sub { shufl @array }, qshuf => sub { qshuf @array }, Ushuf => sub { Ushuf @array }, }); my (%buckets, %d, @temp);; my @set = qw(A B C D); for (1 .. 100_000 ) { $buckets{"@{[slice @temp=@set]}"}{slice}++; $buckets{"@{[xform @temp=@set]}"}{xform}++; $buckets{"@{[shufl @temp=@set]}"}{shufl}++; $buckets{"@{[qshuf @temp=@set]}"}{qshuf}++; $buckets{"@{[Ushuf @temp=@set]}"}{Ushuf}++; } print "\npermutation | slice | xform | shufl | qshuf | Ushuf \n"; print "-------------------------------------------------- \n"; for my $key (sort keys %buckets) { printf "%8.8s: | %4d | %4d | %4d | %4d | %4d\n", $key, $buckets{$key}{slice}, $buckets{$key}{xform}, $buckets{$key}{shufl}, $buckets{$key}{qshuf}, $buckets{$key}{Ushuf}; $d{slice}{Ex} += $buckets{$key}{slice}; $d{slice}{Ex2} += $buckets{$key}{slice}**2; $d{xform}{Ex} += $buckets{$key}{xform}; $d{xform}{Ex2} += $buckets{$key}{xform}**2; $d{shufl}{Ex} += $buckets{$key}{shufl}; $d{shufl}{Ex2} += $buckets{$key}{shufl}**2; $d{qshuf}{Ex} += $buckets{$key}{qshuf}; $d{qshuf}{Ex2} += $buckets{$key}{qshuf}**2; $d{Ushuf}{Ex} += $buckets{$key}{Ushuf}; $d{Ushuf}{Ex2} += $buckets{$key}{Ushuf}**2; } print "---------------------------------------------------\n"; printf "Std. Dev. | %0.3f | %0.3f | %0.3f | %0.3f | %0.3f\n", sqrt( ($d{slice}{Ex2} - ($d{slice}{Ex}**2/24))/23 ), sqrt( ($d{xform}{Ex2} - ($d{xform}{Ex}**2/24))/23 ), sqrt( ($d{shufl}{Ex2} - ($d{shufl}{Ex}**2/24))/23 ), sqrt( ($d{qshuf}{Ex2} - ($d{qshuf}{Ex}**2/24))/23 ), sqrt( ($d{Ushuf}{Ex2} - ($d{Ushuf}{Ex}**2/24))/23 ); __END__ P:\test>200083.pl Rate xform slice qshuf shufl Ushuf xform 153/s -- -40% -55% -75% -95% slice 254/s 66% -- -25% -58% -92% qshuf 338/s 120% 33% -- -45% -89% shufl 611/s 298% 140% 81% -- -80% Ushuf 3077/s 1905% 1111% 811% 404% -- permutation | slice | xform | shufl | qshuf | Ushuf -------------------------------------------------- A B C D: | 4254 | 4093 | 4214 | 6364 | 4121 A B D C: | 4311 | 4104 | 4143 | 6357 | 4198 A C B D: | 4192 | 4084 | 4114 | 3069 | 4071 A C D B: | 4148 | 4367 | 4154 | 3155 | 4065 A D B C: | 4077 | 4188 | 4215 | 3159 | 4244 A D C B: | 4152 | 4098 | 4096 | 3150 | 4204 B A C D: | 4044 | 4170 | 4254 | 6293 | 4247 B A D C: | 4168 | 4091 | 4072 | 6199 | 4251 B C A D: | 4108 | 4075 | 4219 | 3089 | 4097 B C D A: | 4170 | 4182 | 4172 | 3052 | 4169 B D A C: | 4148 | 4136 | 4205 | 3130 | 4215 B D C A: | 4184 | 4186 | 4167 | 3110 | 4278 C A B D: | 4158 | 4220 | 4206 | 3102 | 4130 C A D B: | 4160 | 4329 | 4066 | 3117 | 4116 C B A D: | 4093 | 4180 | 4199 | 3083 | 4090 C B D A: | 4239 | 4270 | 4093 | 2973 | 4148 C D A B: | 4270 | 4158 | 4126 | 6223 | 4185 C D B A: | 4187 | 4176 | 4094 | 6384 | 4215 D A B C: | 4188 | 4113 | 4229 | 3191 | 4070 D A C B: | 4158 | 4095 | 4182 | 3033 | 4180 D B A C: | 4146 | 4144 | 4197 | 3194 | 4197 D B C A: | 4113 | 4181 | 4296 | 3078 | 4208 D C A B: | 4254 | 4192 | 4143 | 6313 | 4149 D C B A: | 4078 | 4168 | 4144 | 6182 | 4152 --------------------------------------------------- Std. Dev. | 65.292 | 74.242 | 59.644 | 1534.618 | 62.057