I was challenged in my last post to deeper check performance of strings. I think it will be quite interesting to test out some cases and say which way of using strings is the best.
In this post, I will check several string usages in PHP 5.6 and PHP 7.
To simplify testing I created a simple function which gets 2 arguments: an array of callable functions to compare (as many as you want) with names to display in summary, and a number of loops to test the function.
<?php function test(array $funcs, $loops = 5000000) { $time = microtime(true); foreach ($funcs as $func) { for ($i = 0; $i < $loops; $i++) { $func["f"](); } echo sprintf("%.2f s <- %s%s", microtime(true) - $time, $func["n"], PHP_EOL); $time = microtime(true); } echo PHP_EOL; }
Single quotes vs double quotes in PHP 7
In the last post, I was checking if single quotes are faster than double ones. The result was quite clear: it doesn’t matter, sometimes single quotes was a little faster, sometimes was double quotes. I call it equal back then. It was tested in PHP 5.6 so what about PHP 7?
The test looks like this:
<?php require "test.php"; $funcs = []; $funcs[] = [ "n" => "single quotes", "f" => function() { $str1 = 'some string in quotes'; } ]; $funcs[] = [ "n" => "double quotes", "f" => function() { $str2 = "some string in quotes"; } ]; test($funcs);
And the results are very similar like in PHP 5.6.
In addition, it is much faster than in PHP 5.6! But I think it is the topic for another post.
And the winner is… none. Or both 😉
Concatenating strings
There are a couple of ways to concatenate strings in PHP. Let’s check it out!
1. concatenate with dot, single quotes
$functs = []; $functs[] = [ "n" => "dot, single quotes", "f" => function () { $str = 'some' . ' ' . 'string' . ' ' . 'concatenation'; }, ];
2. concatenate with dot, double quotes
$functs[] = [ "n" => "dot, double quotes", "f" => function () { $str = "some" . " " . "string" . " " . "concatenation"; }, ];
3. concatenate with variable, single quotes
$functs[] = [ "n" => "variable, single quotes", "f" => function () { $var = 'string'; $str = 'some' . ' ' . $var . ' ' . 'concatenation'; }, ];
4. concatenate with variable, double quotes
$functs[] = [ "n" => "variable, double quotes", "f" => function () { $var = "string"; $str = "some" . " " . $var . " " . "concatenation"; }, ];
5. concatenate with variable inside string, double quotes only
$functs[] = [ "n" => "variable inside string", "f" => function () { $var = "string"; $str = "some $var concatenation"; }, ];
6. concatenate with `sprintf`, single quotes
$functs[] = [ "n" => "sprintf, single quotes", "f" => function () { $str = sprintf('%s %s %s', 'some', 'string', 'concatenation'); }, ];
7. concatenate with `sprintf`, double quotes
$functs[] = [ "n" => "sprintf, double quotes", "f" => function () { $str = sprintf("%s %s %s", "some", "string", "concatenation"); }, ];
Results in PHP 5.6
Results in PHP 7
And the winner is… not `sprintf`, for sure.
Again it doesn’t matter if you use single or double quotes. In PHP 5.6 results for concatenating strings with variable are very similar, so you can use whatever you like. In PHP 7 concatenation with variable inside string is the fastest.
In both cases, concatenation using `sprintf` is the slowest (which is surprising for me).
And again, as you can see, PHP 7 is much faster than PHP 5.6. It’s time to upgrade, indeed.
Concatenating strings with random variable
This test is similar to previous one, but this time concatenation includes randomized variable.
1. concatenate with dot, random variable, single quotes
$functs[] = [ "n" => "random variable, dot, single quotes", "f" => function () { $var = 'string' . rand(0, 1000); $str = 'some' . ' ' . $var . ' ' . 'concatenation'; }, ];
2. concatenate with dot, random variable, double quotes
$functs[] = [ "n" => "random variable, dot, double quotes", "f" => function () { $var = "string" . rand(0, 1000); $str = "some" . " " . $var . " " . "concatenation"; }, ];
3. concatenate with variable inside string, random variable, double quotes only
$functs[] = [ "n" => "random variable inside string", "f" => function () { $var = "string" . rand(0, 1000); $str = "some $var concatenation"; }, ];
4. concatenate with `sprintf`, random variable, single quotes
$functs[] = [ "n" => "random variable, sprintf, single quotes", "f" => function () { $var = "string" . rand(0, 1000); $str = sprintf('%s %s %s', 'some', $var, 'concatenation'); }, ];
5. concatenate with `sprintf`, random variable, double quotes
$functs[] = [ "n" => "random variable, sprintf, double quotes", "f" => function () { $var = "string" . rand(0, 1000); $str = sprintf("%s %s %s", "some", $var, "concatenation"); }, ];
Results in PHP 5.6
Results in PHP 7
And the winner is… not `sprintf`, again.
As you can see, sprintf was the slowest one, again. It is very handy when you must concatenate several strings, especially when you want to format them (like floats). But if you can avoid them, you should use variables inside strings or concatenation with a dot.
Conclusion
My tests prove that it doesn’t matter if you use single or double quotes both in PHP 5.6 and 7. In concatenation test usage of dots and variable inside string were very close to each other, so I call it even.
The biggest surprise was `sprintf` which was the slowest in concatenation, both in PHP 5.6 and 7. It is very interesting, so I’ll think about some deeper tests for `sprintf` itself.
At the end, you can see how much faster is PHP 7 than 5.6. This is a very interesting topic which I’ll cover in future posts for sure. Stay tuned!
Update
As Claudio Silva points out, in PHP 5.6 I have enabled Xdebug extension. In PHP 7 I have not. So the results are a little incomparable. I disabled Xdebug (by passing `-n` parameter which ignores php.ini) and there are the results for PHP 5.6
Concatenations with static strings:
And concatenations with random strings:
As you can see the times are now “only” 2 times slower than in PHP 7. This is a huge difference, with Xdebug enabled they are almost 20 times slower! I think, this could be useful for those, who have Xdebug extension enabled on production 😉 Don’t do that, seriously.
Don’t forget to check out other PHPhyts!
- PHPyths Buster: A great string performance test! (updated)
- PHPyths Buster: Single quotes are faster than double quotes
- PHPyths Buster: Annotations
- PHPyths Buster: End of the project
- PHPyths Buster: Displaying reminders
- PHPyths Buster: Evernote SDK [update]
- PHPyths Buster: Basic application
- PHPyths Buster: Hello World!
- PHPyths Buster: Project environment
- PHPyths Buster: The Project
A couple of things…
Function calls are very expensive. Avoid them whenever possible. And the more arguments being passed to a function also affects performance. Five arguments is far slower than two arguments.
You didn’t use the braced/parsed variables approach, which is my personal preference, and I’ve found it’s quicker than dot-concatenation.
$str = “This is a string with a {$variable}”;
$str = ‘This is a string with a ‘ . $variable;
As far as I know this
$str = “This is a string with a {$variable}”;
is equal to this
$str = “This is a string with a $variable”;
Quick performance test shows, that they are equally fast.
Braces are useful when you want to use array element in string, in that case without braces there will be error. The same for using objects.
$str = “This is a string with a {$variable[0]}”;
Xdebug is known to make PHP run slower.
How about running the same tests with Xdebug disabled?
This is something I didn’t think about. But I certainly should, because results in PHP 5.6 without Xdebug are much better and only 2 times slower than in PHP 7 (and not 20 times). Thank you very much for this comment, now I should adjust my results 😉
But, I think that this results are also useful, I’ve heard about production sites with Xdebug on. Disabling it will speedup the website a lot so I’ll just add one more test suite for PHP 5.6 without Xdebug.
Consider using https://github.com/phpbench/phpbench next time – comes with a lot of detail around error measurement, standard deviation, etc, and you can re-distribute and save the results for other people to compare them.
Nice, I’ll give it a try! I’ll repeat my test using phpbench.