Разница в скорости использования встроенных строк по сравнению с конкатенацией в php5?
-
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.
Это примерно переводится как "Я не доверяю статистике, которую я сам не подделывал".)
Живые бенчмарки:
На самом деле существует тонкая разница при объединении переменных в одинарные и двойные кавычки.
Использованный тест @Adam's
"these are " . $foo
обратите внимание, что следующее выполняется еще быстрее:
'these are ' . $foo;
это связано с тем, что вычисляется "строка", заключенная в двойные кавычки, где "строка", заключенная в одинарные кавычки, просто берется как есть...
Не слишком увлекайтесь попытками оптимизировать операции со строками в PHP.Конкатенация противинтерполяция бессмысленна (при реальной производительности), если ваши запросы к базе данных плохо написаны или вы не используете какую-либо схему кэширования.Пишите свои строковые операции таким образом, чтобы отладка вашего кода позже была легкой, а разница в производительности незначительной.
@uberfuzzy Предполагая, что это всего лишь вопрос о языковых мелочах, я полагаю, что все в порядке.Я просто пытаюсь добавить к разговору, что сравнение производительности между одинарными кавычками, двойными кавычками и heredoc в реальных приложениях бессмысленно по сравнению с реальными потерями производительности, такими как плохие запросы к базе данных.
Любые различия во времени выполнения совершенно незначительны.
Пожалуйста, посмотрите
- Блог Никича:Опровержение Мифа о производительности одинарных кавычек для технического объяснения, как работает интерполяция и конкатенация в PHP и почему абсолютно бессмысленно заботиться об их скорости.
Не тратьте время на подобную микрооптимизацию.Используйте профилировщик для измерения производительности вашего приложения в реальном сценарии, а затем оптимизируйте там, где это действительно необходимо.Оптимизация одного неаккуратного запроса к базе данных, скорее всего, приведет к большему повышению производительности, чем применение микрооптимизации по всему вашему коду.
Кажется, я помню, что разработчик программного обеспечения 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 отдельной операции (будь то интерполяция или конкатенация), не всегда верно для комбинированных операций.