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

StackOverflow https://stackoverflow.com/questions/13620

  •  08-06-2019
  •  | 
  •  

Вопрос

(предположим, 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?

Это было полезно?

Решение

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

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% от скорости, что не является большим потрясением.Анализатор интерполяции посмотрит, ничего не найдет, а затем завершит простым внутренним объединением строк.Даже если объединение было дорогостоящим, интерполятору все равно придется это сделать, после вся работа по разбору переменной и обрезке / копированию исходной строки.

Обновления От 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 debugger с parse.Надеюсь, вы поняли мою точку зрения.

Другие советы

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

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds

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

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

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

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

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

Живые бенчмарки:

http://phpbench.com/

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

Использованный тест @Adam's

"these are " . $foo

обратите внимание, что следующее выполняется еще быстрее:

'these are ' . $foo;

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

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

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

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

Пожалуйста, посмотрите

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

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

Однако, похоже, на данный момент я не могу найти ссылку на обсуждение.

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

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

$a = 'parse' . $this; 

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

$a = "parse $this";

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

таким образом, эти тесты, связанные с процессором, не рассказывают всей истории.

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

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

'parse me '.$i.' times'

чем

"parse me $i times"

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

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

$foo = "hello {$bar}";

быстрее, чем

$foo = "hello $bar";

и то, и другое происходит быстрее, чем

$foo = 'hello' . $bar; 

Практически никакой разницы вообще нет!Посмотрите на тайминги: http://micro-optimization.com/single-vs-double-quotes

Следует отметить, что при использовании модифицированной версии примера Адама Райта с 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.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top