On Fri, Jun 14, 2002 at 02:05:02AM +0100, [EMAIL PROTECTED] wrote: > timethese(-5, { > 'control' => sub {my $k=&next_key()}, > 'plusplus' => sub {my $k=&next_key(); $x{$k}++ }, > 'assign1' => sub {my $k=&next_key(); unless ($y{$k}) {$y{$k}=1}} > });
plusplus and assign1 don't do the same thing. Besides... > Benchmark: running assign1, control, plusplus, each for at least 5 CPU > seconds... > assign1: 5 wallclock secs ( 5.09 usr + 0.00 sys = 5.09 CPU) @ > 39536.66/s (n=201123) > control: 5 wallclock secs ( 5.14 usr + 0.00 sys = 5.14 CPU) @ > 50786.60/s (n=260840) > plusplus: 6 wallclock secs ( 5.03 usr + 0.00 sys = 5.03 CPU) @ > 36624.03/s (n=184109) There's no difference between the two (don't look at the wallclock time, look at the CPU time). > > >> 2) There is a bug Activestate Perl 5.6.0 and onwards for Win32 where > garbage > >> collection of %seen=() or %seen=undef is slow. I reported the bug back > in > >> December, but nothing seems to have happend since. > >> http://bugs.activestate.com//ActivePerl/show_bug.cgi?id=3D18559 > >> I'm surprised there's been no action on this one as garbage collecting > >> hashes I would have thought was critical to object oriented programming. > > > >According to Bugzilla, Guru was unable to reproduce the problem: > > Well on Unix and Win32 5.005 this code runs each loop in constant time > (10,10,10,10). In ActiveState Win32 5.6.0 and 5.6.1 only the first one takes > (10,24,23,23). What do you get? Similar results, but I only have 5.6.1 on Win98. Except this isn't quite doing what you think it's doing... > use strict; > srand(); > for (1..4) { > print "Loop $_ took ".&Do_It." seconds\n"; > } > > sub Do_It { > my $start=time; > my %x=(); > keys(%x)=1e5; > for (my $i=0; $i<1e5;$i++) { > $x{rand().rand().rand().rand().rand().rand()}=$i; > } > return time-$start; > } Since %x is lexical, each call to Do_It() is allocating and deallocating %x every time the subroutine is called. You're not benching the time to reuse %x, you're benching the time to create and destroy %x. In effect, you're doing this: my %x=(); # declare %x. sub Do_It { my $start=time; keys(%x)=1e5; # extend %x to accomodate 1e5 keys for (my $i=0; $i<1e5;$i++) { $x{rand().rand().rand().rand().rand().rand()}=$i; } undef %x; # free all the memory used by %x # so you have to reallocate it all # over again. return time-$start; } what you should be doing, if you want to benchmark the time to clear and large hash, not free the memory, is something like: my %x=(); keys(%x)=1e5; sub Do_It { my $start=time; for (my $i=0; $i<1e5;$i++) { $x{rand().rand().rand().rand().rand().rand()}=$i; } %x = (); return time-$start; } but I think I've just confirmed your bug. This takes (6,24,23,23) for me with Activestate build 631 and (11,11,13,11) with Linux/PowerPC 5.6.1. So I dunno. It would be worth trying with a Perl on Unix which is compiled similarly to how ActiveState does it, ie. with iThreads and multiplicity and all that, to see if it's just something about the configuration or something ActiveState's done. The only one I have like that is 5.8.0 compiled with debugging flags. It also might be worth trying a stock Win32 compilation. -- This sig file temporarily out of order.