3

元の作成者が配列を使用して Web ページを作成したコードを次のように変更しています。

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

これが望ましい(またはその逆)理由を誰でも考えることができますか?

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

10 に答える 10

13

おそらく、文字列が不変であるため連結が高価な言語の出身者によって書かれたのでしょう。次のテストが示すように、PHP はそれらの 1 つではありません。したがって、2 番目のアプローチは、パフォーマンスに優れています。最初のアプローチを使用する他の唯一の理由は、配列の一部を別の部分に置き換えることができるということですが、それは指定されていないインデックスを追跡することを意味します。

~$ 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
于 2008-09-21T16:07:54.323 に答える
2

ちょっと話が逸れますが、

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

出力バッファの動作などにより、これが文字列を構築する最速の方法です。明らかに、スティングの構築を本当に最適化する必要がある場合にのみ、これを行います。そして、「時期尚早の最適化は諸悪の根源」であることは誰もが知っています。

于 2008-09-21T18:25:28.720 に答える
2

繰り返しになりますが、トピックから少し外れますが (それほど遠くない)、出力される配列アイテムの間に何かを配置することを目的としている場合、連結する行が数行しかない場合は、 join(', ', $output) で十分です。それは簡単かつ迅速に十分です。これにより、記述が容易になり、リストの末尾をチェックする必要がなくなります (末尾の ',' が不要な場所)。

プログラマーの時間については、CPU サイクルよりも 1000 倍もコストがかかるため、通常、1 秒あたり 10,0000 回以上実行されない場合は、結合に投入します。

このようなコーディング後のマイクロ最適化は、かかる時間と節約される CPU 時間の点で価値があることはほとんどありません。

于 2008-09-22T09:00:35.433 に答える
1

<!-- 前のコメントを削除 -->

コードにエラーがあったように見えるので、ノーオペレーションを行っていて、チェックするのを忘れていました。

以前のテストに反して、このトピックに関する以前のブログを読むと、少なくとも上記のコードのすべてのバリアントについて、次の結論は実際には (テスト済み)真実ではありません。

  1. UNTRUE : 文字列の補間は、文字列の連結よりも低速です。(!)
  2. UNTRUE : SprintF が最速です。

実際のテストでは、Sprintf が最も遅く 、補間が最も高速でした

PHP 5.2.6-pl7-gentoo (cli) (ビルド: 2008 年 9 月 21 日 13:43:03)
Copyright (c) 1997-2008 PHP グループ
Zend Engine v2.2.0、Copyright (c) 1998-2008 Zend Technologies
    Xdebug v2.0.3 を使用、Copyright (c) 2002-2007、Derick Rethans 著

私のセットアップの条件かもしれませんが、それでも奇妙です。:/

于 2008-09-21T16:19:58.727 に答える
1

それを行う最も速い方法は、エコーを使用することだと思います。見栄えが悪く、読みやすさのコストに見合うほど高速ではない可能性があります。

echo $stuff_from_database
   , 'more stuff'
   , 'yet more'
   // etc
   , 'last stuff';
于 2008-09-22T14:28:28.720 に答える
0

implode()またはと結合するとjoin()、PHP はそれをより適切に最適化できます。リスト内のすべての文字列を調べ、長さを計算し、必要なスペースを割り当ててスペースを埋めます。「.=」と比較すると、常にfree()文字malloc()列用のスペースが必要です。

于 2008-09-21T16:12:55.530 に答える
0

下部は $output 文字列を繰り返し再割り当てしますが、上部は各ピースを配列に格納し、最後にそれらをすべて結合すると思います。結果として、元の例の方が高速になる可能性があります。これがパフォーマンスに影響されない場合は、おそらく結合ではなく追加します。

于 2008-09-21T16:00:01.970 に答える
0

コードのこの部分はパフォーマンスに依存しません。トラフィックの少ない Web サイトでユーザーのショッピング カート情報をフォーマットして表示するために使用されます。また、配列 (または文字列) は毎回ゼロから構築されるため、特定の要素をアドレス指定したり検索したりする必要はありません。配列の方がやや効率的であるように思えますが、この用途ではどちらの方法でも問題ないと思います。すべての情報をありがとう!

于 2008-09-24T02:02:03.020 に答える
0

リスト (ショッピング カートなど) を生成する場合は、データベースから取得した各エントリから HTML を生成するコードが必要です。

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

またはそのようなもの。そうすれば、コードはずっときれいになります。もちろん、これは、私の会社が行っている (そして置き換えている) ような馬鹿げた混乱ではなく、オブジェクトを含む適切なコードがあることを前提としています。

于 2008-09-24T02:06:24.040 に答える
0

すでに言われていますが、明確な答えが役立つと思います。

元のプログラマーは、その方が速いと思ったので、そのように書きました。実際、PHP 4 では、特に大きな文字列の場合は、実際に高速でした。

于 2009-04-27T00:03:56.860 に答える