in reply to Iterate over HoH without Recursion
Using the code below, I get the following:
I don't know how to benchmark memory usage of each subroutine, but that would be interesting because for a very large data structure, doing it non-recursively may actually be good in terms of memory use.Benchmark: timing 10000 iterations of ZZamboni, chromatic... ZZamboni: 12 wallclock secs ( 5.64 usr + 0.00 sys = 5.64 CPU) chromatic: 19 wallclock secs ( 8.10 usr + 0.01 sys = 8.11 CPU)
Here's the code:
#!/usr/bin/perl -w use strict; use Benchmark; my $tree = ''; my %hash = ( 1 => 1, 2 => { 3 => 4, 5 => { 6 => 7 }, }, 8 => 9, 10 => {}, ); sub ZZamboni { my %hash=%{$_[0]}; my $level=$_[1]; my $tree=''; my $key; foreach $key (sort { $a <=> $b } keys %hash) { $tree .= "\t" x $level . "$key => "; if (ref($hash{$key})) { $tree .= "\n" . ZZamboni($hash{$key}, $level+1); } else { $tree .= $hash{$key} . "\n"; } } return $tree; } sub chromatic { my %hash=%{$_[0]}; my @stack; push @stack, \%hash; my $level = 0; my $tree=''; while (@stack) { my ($hash_ref, $keys_ref); if (ref($stack[-1]) eq 'ARRAY') { ($hash_ref, $keys_ref) = @{ pop @stack }; $level--; } else { $hash_ref = pop @stack; $keys_ref = [ sort { $b <=> $a } (keys %$hash_ref) +]; } while (my $key = pop @{ $keys_ref }) { my $value = $hash_ref->{$key}; if (ref($value) eq 'HASH') { $tree .= "\t" x $level . "$key => \n"; push @stack, ([ $hash_ref, $keys_ref ], $va +lue); $level++; last; } else { $tree .= "\t" x $level . "$key => $value\n" +; # print "on key $key, stack is ", $level, " l +evels deep.\n"; } } } return $tree; } timethese(10000, { 'ZZamboni' => sub { ZZamboni(\%hash, 0) }, 'chromatic' => sub { chromatic(\%hash) }, });
--ZZamboni
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Iterate over HoH without Recursion
by tphyahoo (Vicar) on Nov 24, 2005 at 15:02 UTC |