Does iterating over a hash reference require implicitly copying it in perl? -
lets have large hash , want iterate on contents of contents. standard idiom this:
while(($key, $value) = each(%{$hash_ref})){ ///do } however, if understand perl correctly doing 2 things. first
%{$hash_ref} is translating ref list context. returning like
(key1, value1, key2, value2, key3, value3 etc) which stored in stacks memory. each method run, eating first 2 values in memory (key1 & value1) , returning them while loop process.
if understanding of right means have copied entire hash stacks memory iterate on new copy, expensive large hash, due expense of iterating on array twice, due potential cache hits if both hashes can't held in memory @ once. seems pretty inefficient. i'm wondering if happens, or if i'm either misunderstanding actual behavior or compiler optimizes away inefficiency me?
follow questions, assuming correct standard behavior.
is there syntax avoid copying of hash iterating on values in original hash? if not hash there 1 simpler array?
does mean in above example inconsistent values between copy of hash , actual hash if modify hash_ref content within loop; resulting in $value having different value $hash_ref->($key)?
no copy created each (though copy returned values $key , $value through assignment). hash passed each.
each little special. supports following syntaxes:
each hash each array as can see, doesn't accept arbitrary expression. (that each expr or each list). reason allow each(%foo) pass hash %foo each rather evaluating in list context. each can because it's operator, , operators can have own parsing rules. however, can similar \% prototype.
use data::dumper; sub f { print(dumper(@_)); } sub g(\%) { print(dumper(@_)); } # similar each %h = (a=>1, b=>2); f(%h); # evaluates %h in list context. print("\n"); g(%h); # passes reference %h. output:
$var1 = 'a'; # 4 args, keys , values of hash $var2 = 1; $var3 = 'b'; $var4 = 2; $var1 = { # 1 arg, reference hash 'a' => 1, 'b' => 2 }; %{$h_ref} same %h, of above applies %{$h_ref} too.
note hash isn't copied if flattened. keys "copied", values returned directly.
use data::dumper; %h = (abc=>"def", ghi=>"jkl"); print(dumper(\%h)); $_ = uc($_) %h; print(dumper(\%h)); output:
$var1 = { 'abc' => 'def', 'ghi' => 'jkl' }; $var1 = { 'abc' => 'def', 'ghi' => 'jkl' }; you can read more here.
Comments
Post a Comment