in reply to Add a list of numbers together

  1. First off, i43s's code fails to compile for me using perl 5.6.0 with -w, with the following:
    Warning: Use of "shift" without parens is ambiguous at benchadd.pl line 3. Type of arg 1 to shift must be array (not shift) at benchadd.pl line 3, near "shift,"
    This is fixed by adding explicit parenthesis after every shift().

  2. Second, mdillon's code as is returns undef, because the "my $sum" is part of the loop (I think that's the reason, at least). Separating the declaration of the variable from the suming loop fixes the problem.
  3. Third, I have benchmarked th three solutions proposed so far (i43s, davorg and mdillon) using the code below. The results show:
    Benchmark: timing 100000 iterations of davorg, i43s, mdillon... davorg: 70 wallclock secs (55.52 usr + 0.06 sys = 55.58 CPU) @ 1799.21/s (n=100000) i43s: 20 wallclock secs (15.47 usr + 0.00 sys = 15.47 CPU) @ 6464.12/s (n=100000) mdillon: 8 wallclock secs ( 6.77 usr + 0.00 sys = 6.77 CPU) @ 14771.05/s (n=100000)
    So my comments are:
    • davorg: nice trick with eval, but eval is just too slow.
    • i43s: nice recursive subroutine, but recursion is also expensive, and IMHO it complicates the code in this case.
    • mdillon: that's how I would have done it too :-)

--ZZamboni

The benchmarking code:

use Benchmark; sub add_i43s { @_ > 1 ? add_i43s( shift() + shift(), @_ ) : shift() } sub add_davorg { eval join '+', @_ }; sub add_mdillon { my $sum; $sum += $_ for @_; $sum } timethese(100000, { 'i43s' => sub { add_i43s(1,2,3,4,5,6,7,8,9,10); }, 'davorg' => sub { add_davorg(1,2,3,4,5,6,7,8,9,10); }, 'mdillon' => sub { add_mdillon(1,2,3,4,5,6,7,8,9,10); } });