http://qs1969.pair.com?node_id=11139118


in reply to Hash versus chain of elsifs

In terms of complexity, a hash key look up is always the most efficient being O(1). The drawback, as has been mentioned, is that this requires a key. If you're dealing with a known set of strings, this is as efficient as possible. So to be clear, if you're going to do a cascade of if ( $str eq 'somestring' )... then use a hash look up.

If dealing with a set of conditions (e.g., a range of values), then you need to use a conditional somewhere. The question becomes, how to compute a static hash key from a value (be it a range, regex, mathematical function, etc).

E.g.,

use strict; use warnings; my $value_buckets = { 'first half' => sub { print qq{first half!\n} }, 'second half' => sub { print qq{second half!\n} }, 'third half' => sub { print qq{third half!\n} }, 'not found' => sub { print qq{not found!\n} }, }; my $key = compute_key(42); $value_buckets->{$key}->(); # just an example, could be anything to derive a hash # key from $value sub compute_key { my $value = shift; if ( $value > 0 and $value < 33 ) { return 'first half'; } elsif ( $value >= 33 and $value <= 66 ) { return 'second half'; } elsif ( $value >= 67 and $value <= 100 ) { return 'third half'; } # last resort return 'not found'; }
Output:
# perl test.pl second half!

A related question is, can you write a sophisticated perl program without conditionals that also minimizes the computational complexity? The answer is, "YES"; and if that's your interest I think your exploration may be added by looking at the functional side of Perl. And there's no better place to look than Higher Order Perl for that.

Final note, even though an series of ifels.. statements will terminate when the condition is found; there is nothing to guarantee how far down the litany of conditionals you'll fall. So in terms of computational complexity, it's always going to add a constant factor equivalent to the worst case scenario of having to check all conditions.