Я изменяю код, в котором исходный автор создал веб-страницу, используя массив следующим образом:
$output[]=$stuff_from_database;
$output[]='more stuff';
// etc
echo join('',$output);
Может ли кто-нибудь придумать причину, по которой это было бы предпочтительнее (или наоборот) перед:
$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;






Нижняя часть будет многократно перераспределять строку $ output, тогда как я считаю, что верхняя часть просто сохранит каждую часть в массиве, а затем соединит их все в конце. В результате исходный пример может оказаться быстрее. Если это не зависит от производительности, я бы, вероятно, добавил, а не присоединился.
Вероятно, он был написан кем-то, кто пришел из языка, где строки неизменяемы, и поэтому конкатенация стоит дорого. Как показывают следующие тесты, PHP не входит в их число. Итак, второй подход лучше с точки зрения производительности. Единственная другая причина, по которой я могу использовать первый подход, - это возможность заменить одну часть массива другой, но это означает отслеживать индексы, которые не указаны.
~$ cat join.php
<?php
for ($i=0;$i<50000;$i++) {
$output[] = "HI $i\n";
}
echo join('',$output);
?>
~$ time for i in `seq 100`; do php join.php >> outjoin ; done
real 0m19.145s
user 0m12.045s
sys 0m3.216s
~$ cat dot.php
<?php
for ($i=0;$i<50000;$i++) {
$output.= "HI $i\n";
}
echo $output;
?>
~$ time for i in `seq 100`; do php dot.php >> outdot ; done
real 0m15.530s
user 0m8.985s
sys 0m2.260s
Если соединить с implode() или join(), PHP сможет лучше оптимизировать это. Он просматривает все строки в вашем списке, вычисляет длину, выделяет необходимое пространство и заполняет его. По сравнению с ". =" Он должен постоянно занимать место для строки free() и malloc().
Вы поднимаете хороший вопрос. Будет интересно измерить потребление памяти ... может быть, это узкое место для большого набора данных.
<! - Удален предыдущий комментарий ->
Похоже, в моем коде была ошибка, поэтому я не выполнял никаких действий и забыл проверить.
Похоже, что это противоречит предыдущему тестированию и чтению предыдущих блогов по этой теме, следующие выводы фактически (проверены) неправда, по крайней мере, для всех вариантов приведенного выше кода, которые я могу переставить.
В реальных тестах Sprintf был самый медленный, а интерполяция была самый быстрый.
PHP 5.2.6-pl7-gentoo (cli) (built: Sep 21 2008 13:43:03)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
Это может быть условно для моей установки, но все же странно. : /
Это немного не по теме, но
$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;
Намного медленнее, чем:
echo = $stuff_from_database;
echo 'more stuff';
Фактически, самый быстрый способ построить строку в PHP:
ob_start();
echo = $stuff_from_database;
echo 'more stuff';
$output = ob_get_contents();
ob_end_clean();
Из-за того, как работают выходные буферы и тому подобное, это самый быстрый способ построить строку. Очевидно, вы сделаете это только в том случае, если вам действительно нужно оптимизировать сборку укусов, поскольку это некрасиво и не приводит к легкому чтению кода. И всем известно, что «Преждевременная оптимизация - корень всех зол».
с небольшими исправлениями кода вокруг «echo =» и выводом «$ output», это самый быстрый, потому что буферизация вывода распределяется блоками по 4 или 8 КБ, а не столько, сколько необходимо (всего 1 байт).
Опять же, немного не по теме (не очень далеко), но если вы хотели поместить что-то между выводимыми элементами массива, тогда, если бы было только несколько строк для объединения, join (',', $ output) сделал бы это легко и достаточно быстро. Это было бы проще написать, и вам не нужно было бы проверять конец списка (где вам не нужны завершающие символы ',').
Для программистов, поскольку это примерно в 1000 раз дороже, чем цикл процессора, я обычно просто вставлял его в соединение, если он не собирался запускаться более 10 000 раз в секунду.
Такая микрооптимизация после кодирования очень редко окупается с точки зрения затраченного времени по сравнению с сэкономленным временем процессора.
Я думаю, что самый быстрый способ сделать это - использовать эхо. Это не так красиво и, вероятно, недостаточно быстро, чтобы оправдать затраты на удобочитаемость.
echo $stuff_from_database
, 'more stuff'
, 'yet more'
// etc
, 'last stuff';
Эта часть кода не чувствительна к производительности; он используется для форматирования и отображения информации о корзине покупок пользователя на веб-сайте с низким трафиком. Кроме того, массив (или строка) каждый раз строится с нуля, и нет необходимости обращаться или искать определенные элементы. Похоже, что массив несколько более эффективен, но я думаю, это не имеет значения в любом случае для этого использования. Спасибо за всю информацию!
Если вы создаете список (например, корзину покупок), у вас должен быть код, который генерирует HTML из каждой записи, полученной из базы данных.
for ($prod in $cart)
{
$prod->printHTML();
}
Или что-то вроде того. Таким образом код становится намного чище. Конечно, это предполагает, что у вас есть хороший код с объектами, а не целый идиотский беспорядок, как в моей компании (и заменяет).
Об этом уже было сказано, но, думаю, поможет внятный ответ.
Первоначальный программист написал это так, потому что думал, что это быстрее. Фактически, в PHP 4 это действительно было быстрее, особенно для больших строк.
Это явное улучшение по сравнению с PHP 4, где все было наоборот.