Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

A better non-existant string...

by lzcd (Pilgrim)
on Jan 23, 2001 at 03:15 UTC ( #53617=perlmeditation: print w/replies, xml ) Need Help??

Just a small meditation that wondered past my frontal lobes recently:

In my own code, when I need to see if a string is empty, I go for something along the lines of:
if ($teststring ne '') { ...
As opposed to the more common variation of:
if ($teststring ne "") { ...
My reasoning, up this point, has been that it's less work for the perl engine to compare against a(n almost) literal of '' then have to go through the parse cycle and then compare for a "".

But... recently my brain has been probing the possibility that my assumption is false.

Does perl have a precompiled shortcut for dealing with ""?
Does perl have some magical process where "" is evaluated at the same speed (or faster?) than its '' brethren?

I know in my heart that the difference between the two alternatives is probably no more than a few cycles and I'll probably squander what savings are made through that rather nasty regex further on in the code... but it's been bugging the ol' hamsters wheel for a while now.

Thank you for your microwave popcorn time.

Replies are listed 'Best First'.
(tye)Re: A better non-existant string...
by tye (Sage) on Jan 23, 2001 at 04:24 UTC

    Single- and double-quoted strings both have to be parsed at compile time. Both get compiled into constants and so there is no speed difference between the two at run time.

    Now a string like "We have $n things" actually gets compiled into "We have ".$n." things". The string is not reparsed each time you hit that line of code.

    I had to resort to a 3200-byte string and finally was able to detect at 20% slow-down for double-quoted strings. This means that if your script has four thousand 3200-byte strings enclosed in double quotes, then you could make it start up 0.2 seconds faster by changing all of those double quotes to single quotes. No matter how long the script ran, no further speed benefit would be achieved.

    So "optimizing" 0-byte strings to use single quotes instead of double quotes is just silly. The added complexity to your mental decision tree probably costs more time than you ever save. (:

            - tye (but my friends call me "Tye")
      I was going to disagree, but continue reading to see why I'm not. My code is below, have I done something wrong?
      #!/usr/bin/perl use Benchmark; sub double { $teststring = ''; if( $teststring ne "" ) { return 1; } else { return 0; } } sub single { $teststring = ''; if( $teststring ne '' ) { return 1; } else { return 0; } } timethese( 1000000, { double => 'double( )', single => 'single( )' } );
      Which gave these results on 3 consecutive trials
      Benchmark: timing 1000000 iterations of double, single... double: 3 wallclock secs ( 2.14 usr + 0.00 sys = 2.14 CPU) single: 1 wallclock secs ( 1.86 usr + 0.00 sys = 1.86 CPU) Benchmark: timing 1000000 iterations of double, single... double: 1 wallclock secs ( 1.86 usr + 0.00 sys = 1.86 CPU) single: 2 wallclock secs ( 1.92 usr + 0.00 sys = 1.92 CPU) Benchmark: timing 1000000 iterations of double, single... double: 1 wallclock secs ( 1.89 usr + 0.00 sys = 1.89 CPU) single: 1 wallclock secs ( 1.86 usr + 0.00 sys = 1.86 CPU)
      The way I understand the Benchmark module, system load at the time of benchmarking doesn't
      influence the numbers. Is that statement correct? Does anybody know what's going on?

        It isn't the start-up time. It is probably an effect of the working set "settling in" or any number of other things that can affect benchmark numbers. In general, a 5% or less difference isn't something I would consider "real" as running it an hour later could certainly swing the answer that much. Here is the code I used:

        use Benchmark qw(cmpthese); my $str= "This is a test, " x 200; my $single= "'".$str."'"; my $double= '"'.$str.'"'; cmpthese( -3, { a_double => sub { eval $double }, b_single => sub { eval $single }, c_double => sub { eval $double }, d_single => sub { eval $single }, } );
        I don't have my original results (20% difference), but a re-run gave this:
        Rate a_double c_double b_single d_single a_double 4773/s -- -1% -23% -23% c_double 4830/s 1% -- -22% -22% b_single 6170/s 29% 28% -- -0% d_single 6172/s 29% 28% 0% --
                - tye (but my friends call me "Tye")
Re: A better non-existant string...
by extremely (Priest) on Jan 23, 2001 at 06:43 UTC
    Let's check it out with today's favorite toy (Deparse):
    # perl -MO=Deparse,-p -we 'print "Eek\n" if (shift ne "");' ((shift(@ARGV) ne '') and print("Eek\n")); -e syntax OK # perl -MO=Deparse,-p -we "print 'Eek\n' if (shift ne '');" ((shift(@ARGV) ne '') and print('Eek\\n')); -e syntax OK

    It would seem that perl is smart enough at compile time to fix that up for you, just like you would expect.

    $you = new YOU;
    honk() if $you->love(perl)

      And we have a winner...
Re: A better non-existant string...
by Adam (Vicar) on Jan 23, 2001 at 03:36 UTC
    I don't think there is any significant difference between "" and ''. Consider that the metachar \ is still checked in single quoted strings, this means that both types undergo some char check. I find '' to be easier to read, which is a good enough reason to use it (in my book).

    Another point, however, is that I generally encourage people to put the constant first in a comparison. This may seem odd, because its the reverse of how we like to read it, but it results in fewer typos of = versus == type. Really this is the only place it matters, but how often have you tweaked a >= into an = or tweaked an eq into an = ??? So I would check that ( '' ne $teststring ). Also, you know that '' is the equivalence of false. (Of course, so is "0", which is why you would want to be explicit.)

Re: A better non-existant string...
by chromatic (Archbishop) on Jan 24, 2001 at 05:09 UTC
    Since it doesn't matter to Perl, use whichever makes your code more clear.

    I like to use single quotes for things I don't intend to be interpolated, double-quotes for things I do.

    Maybe I'm just a grumpy old crank, but the less things I assume when I code, the better the results.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://53617]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2017-01-21 03:11 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (180 votes). Check out past polls.