I am using
if ( $@ || $c_var eq "" ) {
but constantly read `eq` is expensive.
For example is
if ( $@ || ! length $c_var ) {
better, faster, cheaper
Dear Ian,
I'm not convinced that $var eq "" is necessarily more expensive
than length($var) . The reason I think this is because the eq
operator can report a false value as soon as it detects a character in
the variable it is examining, whereas the length() function must count
every single character in $var, even if $var is millions of characters
long.
The method that is more expensive really depends on the
implementation of the two functions/operators. If you really want to
know which one is more expensinve for the task at hand, use the
Benchmark module (read "perldoc Benchmark" to find out how to use it).
But to be honest, it really doesn't matter which method is better,
faster, cheaper. They are pretty much the same in terms of efficiency.
Sure, one may use up a few more clock cycles than the other, but this
is a small constant value that is practically imperceptable, even by
computer standards (in fact, when I got used the Benchmark module I saw
the warning: "(warning: too few iterations for a reliable count)" even
when I used a count of ten million).
A lot of programmers fall into the trap of thinking that if they
always use the faster, more efficient operators that their code will
run much faster than before. This is true only if the algorithms used
in these options behave better with large data (are you familiar with
Big-O notation?). So if your program can't handle large amounts of
data very well (that is, if it had a Big-O value of N-squared), simply
converting all your '$val eq ""' conditions to '!length($val)' isn't
going to make your program magically handle large amounts of data.
That's because eq and length() have roughly the same Big-O value. To
make your program run faster, you'd have to modify its algorithms so
that none of them are N-squared (or worse). At this point, the use of
eq versus length() is really a moot point.
To illustrate, if using the length() function is one-millionth of a
second faster than using eq, it will only make a noticeable difference
if length() (or eq) is used (on the order of) one million times more
often than anything else (and then, the difference might only be one
second). That is, if you want to check for the existence of an empty
string only five, one hundred, or even a thousand times in your code,
it really won't make a difference whether you use eq or length().
Theoretically, one method will be faster than the other, but you
couldn't time this difference with a stopwatch, even if you had faster
reflexes than anybody else in the world. And like I mentioned above,
even Perl's Benchmark module has trouble perceiving this time
difference.
In my opinion, you should usually use the function/operation that is
more readable (and, of course, you have to decide for yourself which is
more readable). If you spend two minutes converting the code to
something that is theoretically faster, you might not even save one
second of total running time (from every time you run the program).
And if it takes someone in the future three extra minutes to figure out
what you were trying to do, that's more than four minutes and 59
seconds wasted changing your code, thinking that your code will become
faster, better, cheaper.
I realize I wrote a lot about this subject, but to summarize, let me
say this:
Making code run faster almost always means eliminating the
bottlenecks. Changing '$var eq ""' to '!length($var)' might make a
difference (probably super small) but it won't eliminate a bottleneck.
Here is a real-world analogy (if you like these kinds of things):
There is a ten-mile-long road that people drive their cars on. Most
of this road has two lanes. But for some reason, five miles along the
road, the two lanes merge into one lane, but only for 100 meters (after
which they become two lanes again).
Ordinarily this isn't a problem when there are few cars on the road.
As a car reaches the place where the two lanes become one, it switches
lanes (if needed), and then switches back when there are two lanes
again.
But during periods of heavy traffic, this lane merge causes a
bottleneck. Multiple cars are trying to squeeze into one lane at the
same time, creating a bottleneck and backing up traffic for miles.
This is unacceptable, and a solution must be found.
Someone might say that the speed limit should be raised from 55 mph
to 60 mph, because 60 mph is faster, and therefore more efficient, and
will make the cars move faster. Another person might say to make the
stretch of road that only has one lane shorter so that there is more of
the road with two full lanes.
Their intentions are good, but none of these solutions eliminate the
bottleneck, which is what is slowing down traffic. A solution that is
much better than either of those just listed would be to insert a
second lane (where there is currently only one lane) for cars to use
instead of having to merge. (In fact, you could even reduce the speed
limit to 50 mph with this solution and it would still work better than
the solution to only raise the speed limit to 60 mph!)
And while raising the speed limit to 60 mph sounds good, it won't
even save you a full minute when the bottleneck is present. With the
bottleneck, the traffic might be backed up for hours, so just
eliminating one minute won't make all that much difference. Eliminate
the bottleneck and hours of driving time will be saved, even when the
speed limit is significantly slower.
And that's why I think you shouldn't worry about whether you should
use eq or length(). Just go with the one that is more readable and
easier to maintain and understand, and you will end up saving more time
in the future by not having to figure some possibly convoluted code
that might not make much difference in the end at all.
This quote is widely attributed to Donald Knuth:
"Premature optimization is the root of all evil."
The point of the quote is that if you try to optimize a section of code
before you can prove that it needs to be optimized, you may end up
writing obfuscated, difficult-to-read code for nothing.
I hope this helps, Ian.
-- Jean-Luc Romano