Разница в скорости при использовании встроенных строк против конкатенации в php5?

(предположим, что php5) рассмотрим

<?php

    $foo = 'some words';

    //case 1
    print "these are $foo";

    //case 2
    print "these are {$foo}";

    //case 3
    print 'these are ' . $foo;
?>

Есть ли большая разница между 1 и 2?

Если нет, то между 1/2 и 3?

Ответ 1

Ну, как и во всех вопросах "Что может быть быстрее в реальной жизни", вы не можете побить реальный тест на жизнь.

function timeFunc($function, $runs)
{
  $times = array();

  for ($i = 0; $i < $runs; $i++)
  {
    $time = microtime();
    call_user_func($function);
    $times[$i] = microtime() - $time;
  }

  return array_sum($times) / $runs;
}

function Method1()
{ 
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are $foo";
}

function Method2()
{
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are {$foo}";
}

function Method3()
 {
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = "these are " . $foo;
}

print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";

Дайте ему несколько прогонов, чтобы перечислить все, а затем...

0.0035568

0.0035388

0.0025394

Итак, как и ожидалось, интерполяция практически идентична (различия уровня шума, возможно, из-за дополнительных символов, которые должен обрабатывать механизм интерполяции). Прямая конкатенация составляет около 66% скорости, что не вызывает большого шока. Интерполяционный парсер будет выглядеть, ничего не поделать, а затем завершить с помощью простой внутренней строки concat. Даже если concat был дорогим, интерполятору все равно придется это делать, после всю работу, чтобы разобрать переменную и обрезать/скопировать исходную строку.

Обновления от Somnath:

Я добавил Method4() к логике реального времени.

function Method4()
 {
  $foo = 'some words';
  for ($i = 0; $i < 10000; $i++)
    $t = 'these are ' . $foo;
}

print timeFunc('Method4', 10) . "\n";

Results were:

0.0014739
0.0015574
0.0011955
0.001169

Если вы просто объявляете только строку и не нуждаетесь в синтаксическом анализе этой строки, то зачем путать отладчик PHP для разбора. Надеюсь, вы поняли мою точку зрения.

Ответ 2

Разница в производительности была неактуальной с по крайней мере в январе 2012 года и, вероятно, раньше:

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds

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

Никогда не доверяйте статистике, которую вы не создали.

(Хотя в статье цитируется фраза, оригинальная фраза скорее всего была ложно отнесена к Уинстону Черчиллю, изобретенному службой пропаганды Джозефа Геббельса, чтобы изобразить Черчилль как лжец:

Ich traue keiner Statistik, die ich nicht selbst gefälscht habe.

Это свободно переводит: "Я не доверяю статистике, которую я не подделывал сам." )

Ответ 3

Текущие тесты:

http://phpbench.com/

На самом деле существует тонкая разница при объединении переменных с одиночными или двойными кавычками.

Ответ 4

Используемый тест ADAM

"these are " . $foo

обратите внимание на следующее:

'these are ' . $foo;

это связано с тем, что вычисляется двойная кавычка "строка", где только одна строка "строка" принимается так же, как...

Ответ 5

Не пытайтесь оптимизировать строковые операции в PHP. Конкатенация против интерполяции бессмысленна (в реальном мире), если ваши запросы к базе данных плохо написаны или вы не используете какую-либо схему кэширования. Напишите свои строковые операции таким образом, чтобы отладка кода позже была простой, различия в производительности незначительны.

@uberfuzzy Предполагая, что это всего лишь вопрос о языковой миниатюре, я полагаю, это хорошо. Я просто пытаюсь добавить к разговору, что сравнение производительности между одиночной кавычкой, двойной кавычкой и heredoc в приложениях реального мира бессмысленно по сравнению с реальными поглотителями производительности, такими как плохие запросы к базе данных.

Ответ 6

Любые различия во времени выполнения полностью ничтожны.

См.

Не тратьте время на такие микро-оптимизации. Используйте профилировщик для измерения производительности вашего приложения в реальном мире, а затем оптимизируйте, где это действительно необходимо. Оптимизация одного неактивного DB-запроса, скорее всего, приведет к увеличению производительности, чем применение микро-оптимизаций по всему вашему коду.

Ответ 7

Кажется, я помню, что разработчик программного обеспечения форума Vanilla заменил все двойные кавычки в своем коде одиночными кавычками и заметил разумное увеличение производительности.

Я пока не могу найти ссылку на обсуждение в данный момент.

Ответ 8

существует разница при объединении переменных... и то, что вы делаете с результатом... и если то, что вы делаете, это сброс на вывод, это или не выводит буферизацию.

также, что такое ситуация с памятью сервера? обычно управление памятью на платформе более высокого уровня хуже, чем на более низких платформах...

$a = 'parse' . $this; 

управляет памятью на уровне платформы пользовательского кода...

$a = "parse $this";

управляет памятью на уровне платформы платформы php...

поэтому эти тесты, связанные с ЦП, не рассказывают всю историю.

запуск теста в 1000 раз против запуска теста 1000 раз на сервере, который пытается запустить такое же моделирование 1000 раз одновременно... вы можете получить совершенно разные результаты в зависимости от области применения.

Ответ 9

Двойные кавычки могут быть намного медленнее. Я читал из нескольких мест, что лучше сделать это

'parse me '.$i.' times'

чем

"parse me $i times"

Хотя я бы сказал, что второй дал вам более читаемый код.

Ответ 11

Просто добавьте что-то еще в микс, если вы используете переменную внутри синтаксиса с двойной кавычкой:

$foo = "hello {$bar}";

быстрее, чем

$foo = "hello $bar";

и оба они быстрее, чем

$foo = 'hello' . $bar; 

Ответ 12

Следует отметить, что при использовании модифицированной версии примера Адама Райта с 3 переменными результаты меняются на противоположные и первые две функции выполняются быстрее, последовательно. Это с PHP 7.1 на CLI:

function timeFunc($function, $runs)
{
    $times = array();

    for ($i = 0; $i < $runs; $i++)
    {
        $time = microtime();
        call_user_func($function);
        @$times[$i] = microtime() - $time;
    }

    return array_sum($times) / $runs;
}

function Method1()
{ 
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are $foo, $bar and $bas";
}

function Method2()
{
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are {$foo}, {$bar} and {$bas}";
}

function Method3()
{
    $foo = 'some words';
    $bar = 'other words';
    $bas = 3;
    for ($i = 0; $i < 10000; $i++)
         $t = "these are " . $foo . ", " . $bar . " and " .$bas;
}

print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";

Я также пробовал с "3" вместо целого числа 3, но получаю одинаковые результаты.

С $bas = 3:

0.0016254
0.0015719
0.0019806

С $bas = '3':

0.0016495
0.0015608
0.0022755

Следует отметить, что эти результаты сильно различаются (я получаю вариации около 300%), но средние значения кажутся относительно устойчивыми и почти (9 из 10 случаев) всегда показывают более быстрое выполнение для 2 первых методов, с методом 2 всегда немного быстрее, чем метод 1.

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