|laziness, impatience, and hubris|
Perl and common subexpressionsby Stevie-O (Friar)
|on Dec 23, 2004 at 06:24 UTC||Need Help??|
While talking to revdiablo about the details behind the behavior of $_ vs. argument passing, I threw together this example of where things in Perl aren't always well-understood.
In C, the following code:
gets compiled very efficiently with optimizations turned on, due to a standard optimization called 'common subexpression elimination' (heretofore referred to as 'CSE'). In effect, the compiler does this:
Thus, the compiler only has to perform all these dereferences *once*. Unfortunately, unlike C, Perl has to contend with something a little crazier: Tied hashes and arrays. The nature of tied hashes and arrays makes certain things impossible, including CSE. To illustrate my point, I created a benchmark:
The results on my machine are as such:
Note carefully that with_common runs 24% faster than without_common. That's because, even with the extra variable, the three array index and two hash key lookups saved in with_common more than compensate for the extra variable assignment.
Also note the 4-5% difference between with_common/without_common and their _g equivalents. This is *entirely* due to the extra hash lookup required to get the address of the global 'bogus2'. This hash lookup is ALWAYS required due to dynamic scoping requirements.
Morals of the story:
Update: Realized how long this node is, added readmore.