ELISHEVA has asked for the wisdom of the Perl Monks concerning the following question:
Is there a more efficient and self-documenting way to see if a hash is empty than scalar(@{[%h]}) (or scalar(keys %h))?
Neither of these expressions seem to be particularly clear ways of saying "is this empty?". The first especially requires a fairly good understanding of hashes and references to even guess what it is doing. I can't seem to find any function or sub with a clearer-than-day name like is_hash_empty(%h). Am I missing something?
Additionally, both incantations seem like overkill. Checking for emptiness only requires a simple one-step operation to see if at least one key exists. On the other hand [%h] and keys %h copy elements to a new array and are O(N) rather than O(1)... unless, of course, Perl is doing some clever optimizations when it sees scalar(...).
Is it? Does Perl know how to optimize expressions like if (scalar(keys %h)) or scalar(@{[%h]}) && ... so that only one element is tested (or only a stored element count is extracted)? And if so, how sensitive is that optimization to variations in syntax, e.g. are things like scalar(foo()) optimized? And if so, how does "Perl" know it needs to optimize?
And if not, what alternative do you recommend? Using a single call to each(...) does not appear to be an option. Calls to each do not reset, so any subsequent sub that tried to walk through hash elements using each would start on the second key rather than the first. Probably not a good thing.
In the CB, some wise monk (my apologies - I can't remember who) - suggested that scalar(%h) might do it - it returns 0 when the array is empty. Is this always true? Is this an O(1) check for emptiness?
For very small hashes having an efficient way to test for emptiness is probably not an issue. However copying an entire hash could end up being very expensive if the hash is either empty or *very* large. And even with smaller hashes repeated O(N) tests add up quickly potentially turning an O(N) problem into O(N^2). So, if there is an O(1) way to test for emptiness in a hash, I really would like to know it.
Many thanks in advance, beth
|
---|