[tags]best practices, php[/tags]
If you're familiar with PHP, the difference between double and single quotes is obvious. Double quotes evaluate variables and control characters (e.g. \n or \r), whereas single quotes do not.
I've been indoctrinated with the "use single quotes whenever possible" methodology, but I never really put it to the test. Is it really worth it for me to go back and look at old code that uses double quotes and change them? Like all best practices, the answer is "maybe."
So I wrote a simple test harness (there's a lot of room for error with these, but I tried my best).
I tried different permutations of which order to run f1(), f2() and f3() they seemed to give similar results no matter which order they were run.
My results were:
Time 1: 2.898087978363 Time 2: 3.5480048656464 Time 3: 2.8503499031067
My interpretation is that quotes versus double quotes isn't as big of a deal as concatenation versus putting variables within double quotes. My guess is that PHP 5.2.0 (which is what I used for the tests) is smarter with strings than older versions.
So really if you look at the test harness there isn't any discernible differences until you hit 2 million iterations and even then nobody gets fired over 0.6 seconds of performance. Chances are it doesn't matter too much, but over time you can write enough code in the right spots or shared in the right open source projects and that few seconds will snowball. After all, I'm not so much concerned about how optimized a script is that I write, but rather how optimized is a script that everyone ends up using. But rather than do mental calculations about whether or not to optimize something, let's just assume that everything should be as optimal as we can stand to write it.
Update: 6 March 2006, I updated the test harness to reflect my intended tests. Update: 7 March 2006, I updated the results to be more clear.



I thought I’d retry the above but do ‘.=’ instead of ‘=’ in the $c assign step…..
Results were pretty much the same….
Time 1: 3.4265580177307 Time 2: 3.4559869766235 Time 3: 4.0006268024445
(PHP 5.2.1 with APC)
Time 1: 3.3562788963318 Time 2: 3.3513250350952 Time 3: 3.904275894165
(PHP 5.2.1 without APC)
(I’m not sure what should be read into using APC on a cli test)
I’m not very familiar with APC on CLI either or if it runs at all. There’s a slight overhead if you don’t initialize
$cahead of time, because of scoping (i.e. it looks to see if $c is defined in the for loop, or in the containing function, or elsewhere globally).Wow, this code emits an impressive number of E_NOTICE errors!
Interesting discussion, some thoughts:
I ran these tests many times (each in their own file) and consider the two concatenation tests to have identical times. The variable within double quotes however is clearly slower. ~1.92 vs ~2.51. It looks like over time the geeky dev team did some optimizations… good!
As you and most agree with, this sort of optimization is not worth worrying about, at least, not worth “fixing” old code over. Most would agree that readability is key here. So if TRUE is easier to read than true then use TRUE even knowing it’s a few microseconds slower. Same with “a $foo”, if this were longer I’m sure most agree it’s easier to read as one string instead of 100 ”.”.” everywhere (or use heredoc, but that falls into the “a $foo” category).
So yeah I agree with your conclusion. Write optimal code, even saving nanoseconds, as long as readability isn’t reduced.
The joys of having your code left for public consumption?
What were the E_NOTICE warnings? I was unable to get them to display, so what version are you running of PHP? I’m using 5.2.0
Please see:
In PHP4:
f1 and f3 compile to the exact same code so the only difference is the time it takes is for the php to compile it to bytecodes. (A proper test would be to have a huge set of strings in double quotes and single quotes and test how long it takes to run that file from start to finish). A code cache eliminates the difference in all cases since it eliminates the compile step.
As for the other part: the Zend Engine parses a embedded varaible into INIT_STRING, ADD_STRING, and ADD_VAR calls, instead of using the CONCAT operator. I think an optimizer could save something there.
I hope this helps.
terry
The amount of E_NOTICE will be reduced if you actually concat $k with the string instead of the non-initialised $i.
Nice figures.
Merlijn, thanks for catching my typo. I had meant to use
$ias my iterator and then switched to$k. I’ll update this code and result to reflect my intentions.Time 1: 2.898087978363 Time 2: 3.5480048656464 Time 3: 2.8503499031067
Funny, that looks to me like test 3 (single quote with concatenation) is the fastest, yet your narrative says different. Perhaps too many updates to the test codes and results without updating the tests?
Anyway, as you mentioned, the single versus double question is irrelevant next to the interpolated versus concatenated question. For a detailed breakdown of the differences between string types and why interpolation is not a good thing, take a look at: http://blog.libssh2.org/index.php?/archives/28-How-long-is-a-piece-of-string.html
You may never look at heredocs the same again.
Take 2:
Try adding a $ in the strings to see a dramatic difference:
http://pastebin.ca/385302
I should probably be clear as to my end since it agrees with Sara.
I expect that Time 1 and Time 3 should be identical (to within the MoE) because they compile to the exact same thing. I expect Time 2 to be worse because string interpolation isn’t optimized in compilation (unless you have an optimizer).
Thanks Sara for that link that reveals precisely the background information that I’m interested in.
I clarified my explanation in this post. The result for what’s more efficient was irrelevant between double and single quotes (without string variables). The resulting op code in something like this:
$s = "this is a $string";Was very revealing.
It’d be nice to compile a list of “best practices” with supporting evidence in a wiki or some other repository. Perhaps something like this exists.
Thank you man for this nice tutorial! Will consider writing an article about it, too.
Hi, this instruction is more slow: $c = “test {$i}”;
I realized the difference between ” and “” a little bit late. So since two years I have a 18k script in production that’s called about 1000 times per day.
After reading about speed concerns I changed all ” to ‘ (where no substitution is needed). That were about 650 occurrences.
Testing speed after that gave me the result that all the time is spent on database calls
So don’t waste your time on optimizing quotes when you have bigger time consumptive parts -> profile first!
But I agree that one should use single quotes whenever possible.