in reply to Re^3: Speeding up stalled script
in thread Speeding up stalled script
Hello choroba,
Yes, you’re right: despite the calls to delete, the for loop list doesn’t change, so it must be constructed before the first loop iteration.
Whereas using each I get an infinite loop:
use warnings; use strict; use Data::Dump qw(dd pp); my %hash = ( a => 11, b => 12, c => 13, d => 14, ); while (my ($key, $value) = each %hash) { print "key is $key, value is $value, hash is ", pp(\%hash), "\n"; delete $hash{$_} for qw( a b c d ); $hash{x} .= $key; } dd \%hash;
Output:
23:43 >perl 1148_SoPW.pl key is c, value is 13, hash is { a => 11, b => 12, c => 13, d => 14 } key is x, value is c, hash is { x => "c" } key is x, value is cx, hash is { x => "cx" } key is x, value is cxx, hash is { x => "cxx" } key is x, value is cxxx, hash is { x => "cxxx" } key is x, value is cxxxx, hash is { x => "cxxxx" } key is x, value is cxxxxx, hash is { x => "cxxxxx" } key is x, value is cxxxxxx, hash is { x => "cxxxxxx" } key is x, value is cxxxxxxx, hash is { x => "cxxxxxxx" } key is x, value is cxxxxxxxx, hash is { x => "cxxxxxxxx" } ...
Which isn’t surprising given the warning in the documentation for each:
If you add or delete a hash's elements while iterating over it, the effect on the iterator is unspecified; for example, entries may be skipped or duplicated--so don't do that. Exception: It is always safe to delete the item most recently returned by each()...
So it appears that sundialsvc4’s concern over memory is justified: for a large hash, the use of keys in a for loop will consume significantly more memory than the equivalent use of each. It seems strange to me that the documentation doesn’t highlight this — or did I just miss it somewhere?
Cheers,
Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^5: Speeding up stalled script
by BrowserUk (Patriarch) on Feb 05, 2015 at 14:30 UTC | |
by Athanasius (Archbishop) on Feb 05, 2015 at 14:38 UTC |