[LA.pm] Double versus single quotes

Jeff Yoak jeff at yoak.com
Tue Nov 25 18:09:59 CST 2003


On Tue, 2003-11-25 at 14:51, Benjamin J. Tilly wrote:

> Insert usual lecture on premature optimization.  If you have
> never seen it, then http://www.stevemcconnell.com/cctune.htm
> gives a decent version.

Hi,

	I'm 99% in agreement here, but you expressed yourself so well and
pointed to such an excellent reference that the "Me too." aspect of
responding is uninteresting.  On to the 1%.
	I believe that one of the things that distinguishes very good
programmers is having good habits.  (Of course, one of these good habits
is not trying to optimize inappropriately, but that's the 99% again.) 
Sometimes having good habits means learning about small optimizations
and habitualizing their use.

What's wrong with:

if(grep {$_ eq 'banana'} @fruit){
	print "The monkeys rejoice!\n";
}

The answer is nothing.  You just don't have enough fruit to care.  It is
better to not continue through @fruit once you find a banana.  You would
prefer:

foreach my $fruit (@fruit){
	if($fruit eq "banana"){
		print "The monkeys rejoice!\n";
		last;
	}
}

You might still further prefer:

my %fruit;
@fruit{@fruit}=();
print ... if exists $fruit{'banana'};

depending on what else the program might be doing.

Now, if you have a program that includes the initial grep statement and
you know @fruit is small and will be rarely searched in this fashion, it
would be pretty silly to spend time optimizing to one of the latter
constructions.  You'd barely be able to measure the difference.  The
last construction might even be slower to access once on a small array. 
The reason I mention it is that it is a good habit.  Sometimes you
*will* have a lot of fruit.

Can't you just provide care and thought when it is large?  To a certain
extent you can, but habits are extremely important.  It slows you down
way too much to have to simmer over every line you write, even if you
are aware of all of the issues involved.  If you form habits like this,
you can spend your brain cycles on your algorithms, data structures and
actual problem rather than worrying about whether this particular
instance is one in which you shouldn't allow the internals of grep to
hurt you.

My third code snippet above demonstrates another of my habits.  It
indicates what I mean clearly, I think, because when I wrote it the
following didactic consideration hadn't yet occured to me.  Hashes are
very frequently used to force uniqueness or check existence.  Probably
99% of all code written by others that I've encountered will create a
true hash value for each key which is then never used.  This saves
typing out "exists" even though that is what you mean.  My habit is to
the contrary because it is more efficient this way.  There is only one
undef.  Storing undef as the value in each case is cheaper than storing
a regular scalar in each case.  In the overwhelming majority of cases,
this difference of memory footprint is unimportant.  Choosing that as an
optimization would almost always be a waste of time.  On the other hand,
I learned about this years ago and typing it that way is now completely
automatic.  In the rare cases where it does matter, it isn't something I
have to think about in order to get the benefit.  I think the effort I
made in profiling it and making that decision has paid off.

Maybe this is mere banging the tennis ball instead of bending to pick it
up, and maybe most of the benefit comes from other programmers thinking
something I wrote is "elegant" because of it, but I think in general
being oriented to forming such habits is useful.  Do you type:

mysql -ufoo -p

and then type the password so it doesn't end up in your command history
file instead of including it in the initial command?  I think that is a
good habit.  In many cases, you might not really care, but in other
cases you would.  Doing it this way is probably the best choice.  I
think including the password willy-nilly in the initial command is
probably second choice.  Last choice, IMO, would be to actually think
about it each time.  That would make it too slow, and too occupy your
mind with a very minor detail.

So...  I think habits are important.  I think asking the question of the
OP is probably a good thing.  Other people have indicated how to measure
it.  Find out if it matters, and then habitualize the best way.  In any
particular case, it is unlikely to be an optimization that is important,
but collectively over the course of all the programs you'll ever write
it might be.  As someone else said, in this case it might not matter
even over the whole span of your programming life, but even in that case
it might *still* be worth it because you inevitably learn other things
while investigating a question like this.  Even if it is just how
Benchmark and Deparse and such work.

Cheers,
Jeff






More information about the Losangeles-pm mailing list