This calculates the sum of zero or more counts (non-negative integers) using code that looks nice but in reality sucks. (:
my $sum= map {(1)x$_} @counts; # Just say "No" to this code (:

Replies are listed 'Best First'.
Re: sum of counts
by I0 (Priest) on Jan 17, 2001 at 04:05 UTC
    $sum = unpack'%32L*',pack'L*',@counts;

      Oh, that's awful. It is like 30-times faster than mine and about 3 orders of magnitude faster than tilly's. I've come to expect better from you, I0. (:

              - tye (but my friends call me "Tye")
Re: sum of counts
by coreolyn (Parson) on Jan 17, 2001 at 01:54 UTC

    Ok I'll bite the bullet and ask what the silent majority is thinking. Why does it suck?

    coreolyn

      I guess the basic answer is that it is horribly inefficient in both memory space and CPU time.

      (1)x$_ builds a list of $_-many copies of the number 1. That involves allocating $_-many (which could be hundreds of thousands) SV structs (what Perl stores scalar values in) and an array to hold pointers to all of them. Then the remaining values from @counts are moved "up" to make room so this array of pointers can be copied into place. Repeat this for each count.

      Then map checks the size of the resulting huge list and returns it, throwing away the list which results in at least $sum-many calls to free() which each have to adjust memory management buffer pointers, etc.

      But at least the code looks nice.

              - tye (but my friends call me "Tye")
      That didn't really suck. Now this sucks!
      sub Sum {my @s = @_ ? ((0) x shift, Sum(@_)) : @_} $n = Sum(10..100); print $n;

        Well, I felt it vitally important to see exactly how much of an improvement this really is so I benchmarked it:

        Benchmark: running tilly_l, tilly_s, tye_l, tye_s, each for at least 3 + CPU seconds... Out of memory!
        Oops. Um, let me try that again:
        Benchmark: running tilly_l, tilly_s, tye_l, tye_s, each for at least 3 + CPU seconds... tilly_l: 5.14 CPU @ 0.39/s (n=2) (warning: too few iterations for a reliable count) tilly_s: 3.25 CPU @ 18.44/s (n=60) tye_l: 3.16 CPU @ 443.43/s (n=1403) tye_s: 3.25 CPU @ 1691.22/s (n=5488)
        Ah, yes, an admirable improvement. But my code still looks nicer, which was the point.

        So I win this round... ; )

                - tye (but my friends call me "Tye")

      Well, it is like finding prime numbers using:

      my $p= 0; while( 1 ) { print "$p\n" if (1x++$p) !~ /^(..+)\1+$/; }
      Any questions? (Just kidding. I'll give a real answer in a minute if someone hasn't already beat me to it.)

      I believe Abigail deserves credit for that regex, BTW.

              - tye (but my friends call me "Tye")