Modern PHP, soft skills, productivity and time management.

PHPyths Buster: A great string performance test! (updated)



zrzut-ekranu-2016-10-24-o-20-17-45

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.
zrzut-ekranu-2016-10-24-o-20-16-12

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
zrzut-ekranu-2016-10-24-o-20-09-44

Results in PHP 7
zrzut-ekranu-2016-10-24-o-20-17-05

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
zrzut-ekranu-2016-10-24-o-20-13-09

Results in PHP 7
zrzut-ekranu-2016-10-24-o-20-16-33

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:
zrzut-ekranu-2016-10-24-o-23-00-11

And concatenations with random strings:
zrzut-ekranu-2016-10-24-o-23-00-40

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!

7 Comments

  1. The Digital Orchard

    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;

    • krzych

      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]}”;

  2. Claudio Silva

    Xdebug is known to make PHP run slower.
    How about running the same tests with Xdebug disabled?

    • krzych

      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 😉

    • krzych

      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.

  3. Marco Pivetta

    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.

    • krzych

      Nice, I’ll give it a try! I’ll repeat my test using phpbench.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 Krzych Jończyk

Theme by Anders NorenUp ↑