Производительность расширения переменных против sprintf в PHP

по поводу производительности, есть ли разница между:

$message = "The request $request has $n errors";

и

$message = sprintf('The request %s has %d errors', $request, $n);

в PHP?

Я бы сказал, что вызов функции включает в себя больше вещей, но я не знаю, что PHP делает за кулисами для расширения имен переменных.

спасибо!

5 ответов


во всех случаях второй не будет быстрее, так как вы предоставляете строку с двойными кавычками, которые также должны быть проанализированы для переменных. Если вы собираетесь на микро-оптимизацию, правильный путь:

$message = sprintf('The request %s has %d errors', $request, $n);

тем не менее, я считаю, что секунды медленнее (поскольку @Pekka указал, что разница на самом деле не имеет значения), из-за накладных расходов вызова функции, синтаксического анализа строки, преобразования значений и т. д. Но обратите внимание, что 2 строки кода не эквивалентны, так как во втором случае $Н преобразуется в целое число. если $n - "нет ошибки", то первая строка выведет:

The request $request has no error errors

в то время как второй выход:

The request $request has 0 errors

Это не важно.

любой прирост производительности будет настолько мизерным, что вы увидите его (как улучшение в сотых секундах) только с 10000s или 100000s итераций - если даже тогда.

для конкретных чисел см. этот тест. Вы можете видеть, что он должен генерировать 1 МБ + данных, используя 100 000 вызовов функций для достижения измеримой разницы в сотнях миллисекунд. Вряд ли это реальная ситуация. Даже самый медленный метод ("sprintf () с позиционными параметрами") занимает всего 0.00456 миллисекунд против 0.00282 миллисекунд с самым быстрым. Для любой операции, требующей 100 000 выходных вызовов строк, у вас будут другие факторы (например, сетевой трафик), которые будут на порядок медленнее, чем 100 мс, которые вы можете сохранить, оптимизировав это.

использовать все, что делает ваш код наиболее читаемым и поддерживаемым, для вас и других. Лично мне,sprintf() метод-отличная идея - я должен думать о том, чтобы начать использовать это сам.


был сделан анализ производительности о "переменном расширении против sprintf"здесь.

как говорит @pekka, "делает ваш код наиболее читаемым и поддерживаемым для вас и других". Когда прирост производительности "низкий" (~ менее двух раз), игнорируйте его.

подводя ориентира: PHP оптимизирован для разрешений с двойными кавычками и Heredoc. Percentuals к уважению среднего времени, к вычислению очень длинной строки с использованием только

  • разрешение с двойными кавычками: 75%
  • разрешение heredoc: 82%
  • конкатенация одиночной цитаты: 93%
  • формирование sprintf: 117%
  • формирование sprintf с индексированными параметрами: 133%

обратите внимание, что только sprintf выполняет некоторую задачу формирования (см. бенчмарк "%s%s%d%S%f%s"), и, как показывает @Darhazer, он делает некоторую разницу на выходе. Лучший тест-это два критерия, один только сравнивает время конкатенации (форматер "%s"), другие, включая процесс форматирования - например, "%3d%2.2 f " и функциональные эквиваленты перед развертыванием переменных в двойные кавычки... И более одной контрольной комбинации с использованием коротких строк шаблона.

плюсы и минусы

главные преимущества sprintf, Как показали бенчмарки, очень недорогой форматтер (!). Для общего шаблона я предлагаю использовать vsprintf


для ввода нескольких строковых переменных в строку первая будет быстрее.

$message = "The request $request has $n errors";

и для одиночной впрыски, точка(.) конкатенация будет быстрее.

$message = 'The request '.$request.' has 0 errors';

сделайте итерацию с циклом миллиарда и найдите разницу.

например :

<?php

    $request = "XYZ";
    $n = "0";
    $mtime = microtime(true);
    for ($i = 0; $i < 1000000; $i++) {
            $message = "The request {$request} has {$n} errors";
    }
    $ctime = microtime(true);
    echo ($ctime-$mtime);

?>

в конечном счете 1-й является самым быстрым при рассмотрении контекста одного назначения переменной, которое можно увидеть, глядя на различные критерии. Возможно, однако, использование sprintf-вкуса основных функций PHP может позволить более расширяемый код и быть лучше оптимизирован для механизмов кэширования уровня байт-кода, таких как opcache или apc. Другими словами, приложение определенного размера может использовать меньше кода при использовании метода sprintf. Чем меньше кода вам нужно кэшировать в ОЗУ, тем больше ОЗУ у вас есть для других вещей или более сценариев. Однако это имеет значение только в том случае, если ваши скрипты не будут правильно вписываться в ОЗУ с помощью оценки.