in reply to Re^2: Counting unique elements in an array
in thread Counting unique elements in an array

That is jumping through some hoops to avoid void. SuprisinglyUnsuprisingly (I just looked at it properly) the first one is a lot slower than the map in void context solution, the last one is slowest of all :)

Updated

added the for loop solution to the benchmark, it is nicely faster.
#!/usr/bin/perl use strict; use warnings; use Benchmark; my @strings; my @array; push @strings, $_ x 2 for ("a" .. "z"); for (1..1000) { my $i=int rand $#strings; push @array, $strings[$i] } sub for_loop { my %sums; $sums{$_}++ foreach @array; # print "$_ = $sums{$_}\n" foreach sort keys %sums; } sub map_void { my %sums; map {$sums{$_}++} @array; # print "$_ = $sums{$_}\n" foreach sort keys %sums; } sub nonvoid_1 { my %sums; %sums = map {$_ => ++$sums{$_} } @array; # print "$_ = $sums{$_}\n" foreach sort keys %sums; } sub nonvoid_2 { my %sums; my $last=""; %sums = map { my $n; do { $n = (($last=$_) ... ($last ne $_)) } while $n =~ /E0$/; ($last => $n); } sort @array; # print "$_ = $sums{$_}\n" foreach sort keys %sums; } timethese( -3, {map_void => \&map_void, for_loop => \&for_loop, nonvoid_1 => \&nonvoid_1, nonvoid_2 => \&nonvoid_2 } ); __END__ Benchmark: running for_loop, map_void, nonvoid_1, nonvoid_2 for at lea +st 3 CPU seconds... for_loop: 3 wallclock secs ( 3.13 usr + 0.01 sys = 3.14 CPU) @ 15 +79.94/s (n=4961) map_void: 3 wallclock secs ( 3.19 usr + 0.00 sys = 3.19 CPU) @ 11 +65.83/s (n=3719) nonvoid_1: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 33 +0.06/s (n=1043) nonvoid_2: 3 wallclock secs ( 3.28 usr + 0.00 sys = 3.28 CPU) @ 13 +9.33/s (n=457)

Cheers,
R.

Pereant, qui ante nos nostra dixerunt!

Replies are listed 'Best First'.
Re^4: Counting unique elements in an array
by Roy Johnson (Monsignor) on Feb 08, 2005 at 18:54 UTC
    That is jumping through some hoops to avoid void.
    Well, yeah. I was posting them in sort of a humor/brainteaser vein rather than as a serious solution to a problem that is (as has been pointed out)
    1. probably homework, and
    2. a FAQ

    Incidentally, here's a method that benches about 9% faster than for_loop:

    sub new_guy { my %sums; ++$_ for @sums{@array}; }

    Caution: Contents may have been coded under pressure.

      cunning indeed, significantly faster.

      Benchmark: running for_loop, map_void, new_guy, nonvoid_1, nonvoid_2 f +or at least 3 CPU seconds... for_loop: 4 wallclock secs ( 3.19 usr + 0.00 sys = 3.19 CPU) @ 15 +55.17/s (n=4961) map_void: 3 wallclock secs ( 3.29 usr + 0.00 sys = 3.29 CPU) @ 11 +30.40/s (n=3719) new_guy: 3 wallclock secs ( 3.07 usr + 0.00 sys = 3.07 CPU) @ 19 +67.10/s (n=6039) nonvoid_1: 3 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 33 +9.37/s (n=1069) nonvoid_2: 3 wallclock secs ( 3.15 usr + 0.01 sys = 3.16 CPU) @ 13 +9.87/s (n=442)

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!