php: output [] w / join против $ output. = - PullRequest
3 голосов
/ 21 сентября 2008

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

 $output[]=$stuff_from_database;
 $output[]='more stuff';
 // etc
 echo join('',$output);

Может ли кто-нибудь придумать причину, по которой это было бы предпочтительным (или наоборот):

 $output =$stuff_from_database;
 $output .='more stuff';
 // etc
 echo $output;

Ответы [ 10 ]

13 голосов
/ 21 сентября 2008

Вероятно, он был написан кем-то из языка, в котором строки неизменны и, следовательно, конкатенация стоит дорого. 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
2 голосов
/ 22 сентября 2008

Опять-таки, немного не по теме (не очень далеко), но если вы намеревались поместить что-то между выводимыми элементами массива, то, если было только несколько строк для объединения, объедините (',', $ output ) сделал бы это легко и достаточно быстро. Это было бы легче написать, и избавило бы от необходимости проверять конец списка (там, где вы не хотели бы конечного ',').

Для программиста, так как он в 1000 раз дороже, чем цикл процессора, я обычно просто выбрасываю его в объединение, если он не будет запускаться более 10 000+ раз в секунду. .

Такая микрооптимизация после кодирования очень редко стоит с точки зрения затраченного времени и сэкономленного времени процессора.

2 голосов
/ 21 сентября 2008

Это немного не по теме, но

$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();

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

1 голос
/ 22 сентября 2008

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

echo $stuff_from_database
   , 'more stuff'
   , 'yet more'
   // etc
   , 'last stuff';
1 голос
/ 21 сентября 2008

<<b>! - Отредактировано Предыдущий комментарий ->

Похоже, в моем коде произошла ошибка, поэтому я не выполнял операции и забыл проверить.

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

  1. UNTRUE : интерполяция строк выполняется медленнее, чем конкатенация строк. (!)
  2. UNTRUE : SprintF самый быстрый.

В реальных тестах 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

Это может быть условно для моей настройки, но все еще странно. : /

0 голосов
/ 27 апреля 2009

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

Оригинальный программист написал это так, потому что думал, что это быстрее. На самом деле, в PHP 4 это действительно было быстрее, особенно для больших строк.

0 голосов
/ 24 сентября 2008

Если вы генерируете список (например, корзину), у вас должен быть какой-то код, который генерирует HTML из каждой записи, извлекаемой из базы данных.

for ($prod in $cart)
{
  $prod->printHTML();
}

Или что-то в этом роде. Таким образом, код становится намного чище. Конечно, это предполагает, что у вас есть хороший код с объектами, а не целый дебильный беспорядок, как моя компания (и заменяет).

0 голосов
/ 24 сентября 2008

Эта часть кода не чувствительна к производительности; он используется для форматирования и отображения информации о корзине покупок пользователя на веб-сайте с низким трафиком. Кроме того, массив (или строка) создается каждый раз с нуля, и нет необходимости обращаться или искать конкретные элементы. Похоже, что массив несколько более эффективен, но я думаю, что это не имеет никакого значения для этого использования. Спасибо за всю информацию!

0 голосов
/ 21 сентября 2008

Если объединить с implode() или join(), PHP сможет лучше оптимизировать это. Он просматривает все строки в вашем списке, вычисляет длину, выделяет необходимое пространство и заполняет пространство. По сравнению с ". =" Он должен постоянно free() и malloc() место для строки.

0 голосов
/ 21 сентября 2008

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

...