A question of Style, was: SPUG: Sort an array question
Michael R. Wolf
MichaelRunningWolf at att.net
Sun Dec 29 22:38:58 CST 2002
The following message is a courtesy copy of an article
that has been posted to comp.lang.perl.moderated as well.
Jeremy Mates <jmates at sial.org> writes:
> * Michael R. Wolf <MichaelRunningWolf at att.net> [2002-12-28T16:31-0800]:
> > my personal preference would be to go with the 3-part for
> >
> > for (my $i = 0; $i < @array; $i++) {
> > for (my $j = $i+1; $j < @array; $j++) {
> >
> > since it's such a well-known idiom.
>
> More readable for the C folks, but about 60% slower than using the
> .. loop syntax.
>
> http://www.sial.org/code/perl/bench/for-loops.pl
Finding it hard to (intuitively) believe, and not being able to access
your site, I played around with Benchmark myself. Since I'm a C
programmer, my habits tend toward the familiar. I'm finding more and
more that folks don't have a C background. And more and more, I'm
finding that that's not just OK, it's good.
I'll share the code below.
I did find that C-style loops are slower than csh-style loops. In
order to take the list generation out of the loop, I created an array
of indices for the csh-style loop. As expected, it increased the
throughput. Likewise, I pre-calculated the upper bounds for the
C-style loop. It, likewise, increased the throughput, about cutting
the difference between a raw C-style and a csh-style loop. And just
for kicks, I proved what I already (intuitively) knew -- that getting
the element directly (without using the index) is still the fastest
way.
Thanks for pointing me to this new piece of knowledge.
Here's my benchmark code:
================================================================
#! /usr/bin/perl -w
use Benchmark qw(timethese cmpthese);
use constant a_len => 10_000; # How big is the array?
@a = (3.14) x a_len; # A big array of pi.
@a_indices = (0 .. $#a); # A cheat for generating the indices.
$i = 0; # Global. Don't time 'my' autovivication.
$code_hashref = {
"C-ish" => sub { for ($i = 0; $i < @a; $i++) { $a[$i] = 0; } },
"csh-ish" => sub { foreach $i (0 .. $#a) { $a[$i] = 0; } },
"C cheat" => sub { for ($i = 0; $i < a_len; $i++) { $a[$i] = 0; } },
"csh nogen" => sub { foreach $i (@a_indices) { $a[$i] = 0; } },
"csh direct" => sub { foreach $i (@a) { $i = 0; } },
};
$results = timethese(0, $code_hashref);
cmpthese($results);
================================================================
And its output:
================================================================
Benchmark: running C cheat, C-ish, csh direct, csh nogen, csh-ish, each for at least 3 CPU seconds...
C cheat: 4 wallclock secs ( 3.09 usr + 0.00 sys = 3.09 CPU) @ 73.04/s (n=226)
C-ish: 4 wallclock secs ( 3.29 usr + 0.00 sys = 3.29 CPU) @ 58.57/s (n=193)
csh direct: 4 wallclock secs ( 3.28 usr + 0.00 sys = 3.28 CPU) @ 131.30/s (n=430)
csh nogen: 3 wallclock secs ( 3.12 usr + 0.00 sys = 3.12 CPU) @ 86.36/s (n=269)
csh-ish: 4 wallclock secs ( 3.22 usr + 0.00 sys = 3.22 CPU) @ 97.36/s (n=314)
Rate C-ish C cheat csh nogen csh-ish csh direct
C-ish 58.6/s -- -20% -32% -40% -55%
C cheat 73.0/s 25% -- -15% -25% -44%
csh nogen 86.4/s 47% 18% -- -11% -34%
csh-ish 97.4/s 66% 33% 13% -- -26%
csh direct 131/s 124% 80% 52% 35% --
================================================================
--
Michael R. Wolf
All mammals learn by playing!
MichaelRunningWolf at att.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org
More information about the spug-list
mailing list