in reply to Re: Summing Up Array Elements By Group
in thread Summing Up Array Elements By Group

The first one you wrote was the fastest:
Benchmark: timing 1000000 iterations of tin1, tin2, tin3... tin1: 1 wallclock secs ( 0.59 usr + 0.00 sys = 0.59 CPU) @ 16 +86340.64/s (n=1000000) tin2: 1 wallclock secs ( 0.75 usr + 0.00 sys = 0.75 CPU) @ 13 +33333.33/s (n=1000000) tin3: 3 wallclock secs ( 2.22 usr + 0.00 sys = 2.22 CPU) @ 45 +0450.45/s (n=1000000) Rate tin3 tin2 tin1 tin3 450450/s -- -66% -73% tin2 1333333/s 196% -- -21% tin1 1686341/s 274% 26% --
the input to get this was:
$results = timethese(1000000,{ tin1 => '$output[int($_/3)] += $arr[$_] for 0..@arr-1;', tin2 =>'$out[$_] = ($arr[(3*$_)]+$arr[(3*$_+1)]+$arr[(3*$_+2)]) for 0. +.(scalar(@arr)/3 - 1);', tin3=>'for (0..$k) { $output[$_] = $arr[$b] + $arr[$b+1] + $arr[$b +2]; $b += 3; } '}); Benchmark::cmpthese( $results );
Raghu

Replies are listed 'Best First'.
Re^3: Summing Up Array Elements By Group
by ivancho (Hermit) on Jan 21, 2009 at 09:40 UTC
    clearly the massive differences between tin2 and tin3 must at least alert you that something is wrong with the benchmark... Frankly I have no idea what goes on once you start eval-ing strings in the Benchmark module, but from the presented examples, something seems suspicious.

    Here is a benchmark by me

    use Benchmark qw(cmpthese); my @arr = map {rand} 0..900000; my @output = map {rand} 0..300000;; Benchmark::cmpthese(10,{ tin1 => sub { $output[int($_/3)] += $arr[$_] for 0..@arr-1; }, tin2 => sub { $output[$_] = $arr[3*$_] + $arr[3*$_+1] + $arr[3*$_+2] for 0..@arr/3; }, tin3=> sub { my $b = 0; for (0..@arr /3) { $output[$_] = $arr[$b] + $arr[$b+1] + $arr[$b +2]; $b += 3; } } });
    With result
    $ perl ../../../perlmonks/bench-trip.pl Rate tin1 tin2 tin3 tin1 1.81/s -- -41% -46% tin2 3.08/s 70% -- -9% tin3 3.39/s 87% 10% --

      clearly the massive differences between tin2 and tin3 must at least alert you that something is wrong with the benchmark...

      The problem is that his $b kept growing. You fixed it by readding my $b = 0;.

      Which leads to two the second problem: He didn't use warnings. They don't add a penalty, so use them! If they did add a penalty, all the more reason to use them just like in the real code.

      By the way,
      $output[int($_/3)]
      can be written as
      $output[$_/3]