Perhaps a quote from perlsyn is the best answer.
Although not for the faint of heart, Perl does support a goto statement. There are three forms: goto-LABEL, goto-EXPR, and goto-&NAME. A loop's LABEL is not actually a valid target for a goto; it's just the name of the loop.
The goto-LABEL form finds the statement labeled with LABEL and resumes execution there. It may not be used to go into any construct that requires initialization, such as a subroutine or a foreach loop. It also can't be used to go into a construct that is optimized away. It can be used to go almost anywhere else within the dynamic scope, including out of subroutines, but it's usually better to use some other construct such as last or die. The author of Perl has never felt the need to use this form of goto (in Perl, that is--C is another matter).
I beleive that makes it safe to use this way, though LW's comment is worth reading twice. In this case, I think that the result is as 'structured' as many of the alternatives and much cleaner than most of them.
It is also at least as efficient as the Switch module which itself uses goto amongst several other fairly esoteric practices, though obviously far less flexible.
As for the performance, goto is known to be slow, but the benchmarks I've seen offered in this thread so far don't take into account the fact that using if..elsif...else cascades require multiple conditions to be evaluated for those cases near the end of the cascade. Of course this can be mitigated somewhat by careful ordering of the elements if the frequencey distribution of the conditions is predictable, but even then, if all paths are exercised the same number of times, there is no optimal ordering. Using goto bypasses this dilema. Whether this is ever enough to offset the slowness of goto will depend on the application. Used at a high level in the code, with non-trivial conditional code blocks this probably isn't much of a concern. I would definitely favour the hash-based dispatch method for performance critical application though.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.
| [reply] |
Regarding the if/elsif/else comments: I agree. When coding in ASM and 'C', I would always put the highest frequency items first in the chain for performance reasons. It just seems logical that it would apply to any language.
Also, a long time ago, I found that there was a sort of critical mass, if you will, at which point one method was faster than the other. Below that point if/else or cmp/jne etc. was the way to go, the methods were comparable at or near that point, and switch case/jump table was to prefered method over that critical mass.
Now, things have changed, compilers and processors, so I don't know how much that holds true today. I don't write drivers any more so I just don't think about it ;-)
| [reply] |
| [reply] |