I sometimes access a hash like this:
if(exists $ids{$name}){
$id = $ids{$name};
}
Is that good practice? I'm a bit concerned that it contains two lookups where really one should be done. Is there a better way to check the existence and assign the value?
You can do it with one lookup like this:
However, I wouldn't bother unless I saw that that was a bottleneck
performance is not important in this case see "Devel::NYTProf". But to answer your question:
if the value in the hash does not exists, "exists" is very fast
but if it does exists a second lookup is done. if the value is likely to exists than making only one look up will be faster
see this littel benchmark from a perl mailing list.
using a key('xx') that does not exists shows that 'exists' is the winner.
using a key('x') that does exists shows that 'as is_smart' is the winner.
You could use apply Hash::Util's lock_keys to the hash. Then perform your assignments within an eval.
if it is not a multi-level hash you can do this:
or if $id already has a value:
where 'foo' is a default or fall-through value. If it is a multi-level hash you would use 'exists' to avoid the autovivification discussed earlier in the thread or not use it if autovivification is not going to be a problem.
If I want high performance I'm used to write this idiom when want create hash as set:
This code is little bit faster than commonly used
$h{$key}++
.exists
avoids useless assignment andundef
avoids allocation for value. Best answer for you is: Benchmark it! I guess thatexists $ids{$name}
is little bit faster than$id=$ids{$name}
and if you have big miss ratio your version with exists can be faster than assignment and test after.For example if I want fast sets intersection I would wrote something like this.
By checking with
exists
, you prevent autovivification. See Autovivification : What is it and why do I care?.UPDATE: As trendels points out below, autovivification does not come into play in the example you posted. I am assuming that the actual code involves multi-level hashes.
Here is an illustration: