Single Quotes vs. Double Quotes in PHP
In PHP, many times people ask about single quotes vs double quotes, and you see benchmarks all the time that try and show you the differences. It has always made me wonder why this is, and I have finally found out because Sara Golemon, a core contributer for PHP, had a post written about string opcodes, and how they are generated.
From the article:
<?php
echo "This is a constant string";
?>
Yields the nice, simple opcode:
ECHO 'This is a constant string'
No problem… Exactly what you’d expect… Now let’s complicate the expressions a little:
<php
echo "This is an interpolated $string";
?>
Yields the surprisingly messy instruction set:
INIT STRING ~0
ADD_STRING ~0 ~0 'This'
ADD_STRING ~0 ~0 ' '
ADD_STRING ~0 ~0 'is'
ADD_STRING ~0 ~0 ' '
ADD_STRING ~0 ~0 'an'
ADD_STRING ~0 ~0 ' '
ADD_STRING ~0 ~0 'interpolated'
ADD_STRING ~0 ~0 ' '
ADD_VAR ~0 ~0 !0
ECHO ~0
Where !0 represents the compiled variable named $string. Looking at these opcodes: INIT_STRING allocates an IS_STRING variable of one byte (to hold the terminating NULL). Then it’s realloc’d to five bytes by the first ADD_STRING (‘This’ plus the terminating NULL). Next it’s realloc’d to six bytes in order to add a space, then again to eight bytes for ‘is’, then nine to add a space, and so on until the temporary string has the contents of the interpolated variable copied into its contents before being used by the echo statement and finally discarded. Now let’s rewrite that line to avoid interpolation and use concatenation instead:
<?php
echo "This is a concatenated " . $string;
?>
Which yields the significantly shorter and simpler set of ops:
CONCAT ~0 'This is a concatenated ' !0
ECHO ~0
A vast improvement already, but this version still creates a temporary IS_STRING variable to hold the combined string contents meaning that data is duplicated when it’s being used in a const context anyway. Now let’s try out this oft-overlooked use of the echo statement:
<?php
echo "This is a stacked echo " , $string;
?>
Look close, there is a meaningful difference from the last one. This time we’re using a comma rather than a dot between the operands. If you don’t know what the comma is doing there, ask the manual then check back here. Here’s the resulting opcodes:
ECHO 'This is a stacked echo '
ECHO !0
Same number of opcodes, but this time no temporary variables are being created so there’s no duplication and no pointless copying (unless of course $string wasn’t of type IS_STRING, in which case it does have to be converted for output, but don’t get picky now).
So take the benchmark into consideration, changing 2 million double quotes into single quotes will net you about a full second of performance gain!
Oh wait… or you can optimize a single SQL to get that time back.
Moral of the story? Premature optimization is the root of all evil