This sub will return the result of adding a list of numbers together.
sub add { @_ > 1 ? add( shift + shift, @_ ) : shift }

Replies are listed 'Best First'.
RE: Add a list of numbers together
by ZZamboni (Curate) on Jul 01, 2000 at 01:10 UTC
    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); } });
RE: Add a list of numbers together
by davorg (Chancellor) on Jun 29, 2000 at 22:32 UTC
      Syntax error my friend, you must first close the parens that you open. Nice code otherwise.
RE: Add a list of numbers together
by mdillon (Priest) on Jun 29, 2000 at 23:32 UTC
    the recursion is interesting, but i would probably do it like so: sub add { my $sum; $sum += $_ for @_; $sum } update: separated declaration of $sum from for loop after reading ZZamboni's observations.
Re: Add a list of numbers together
by I0 (Priest) on Jan 01, 2001 at 02:43 UTC
    Assuming the sum is positive unpack"%123d*",pack"d*",@_
    Assuming the sum fits a signed longunpack"l",pack"l",unpack"%32d*",pack"d*",@_