そこで、いくつかの実数を取得するために、いくつかのことを実際に定量化することにしました。これがベースライン コードで、100000 個の整数の大きな配列を構築するループです。
$x = array();
for ($idx=0; $idx<100000; $idx++)
$x[] = $idx;
平均実行時間: 85 ミリ秒。これには、PHP を起動し、プログラムを解析し、実行して終了するまでの時間が含まれます。ここで、配列を反復処理する別のループを追加します。
for ($idx=0; $idx<count($x); $idx++) {
;
}
平均実行時間: 105 ミリ秒。85 ミリ秒のセットアップ時間を差し引くと、100,000 個のメンバー配列を反復するのに 20 ミリ秒しかかからないことがわかります。
ここで、ループ不変コード モーションを追加します。
$m = count($x);
for($idx=0; $idx<$m; $idx++) {
;
}
平均実行時間: 90 ミリ秒。
一方で、この節約は莫大です。これは、20 ミリ秒ではなく 5 ミリ秒のループ反復時間です。したがって、75% の節約であると主張できます。
一方、15ミリ秒です。とてつもなく大きな配列では、ほとんどの人が気づくよりも短い時間です。
しかし、これは何もしない配列です。いくつかのデータを出力するとどうなるか見てみましょう:
$m = count($x);
for ($idx=0; $idx<$m; $idx++) {
echo $idx;
}
現在、実行時間は 200 ミリ秒です。おっと、ループ インデックスだけを出力しました。配列の内容も出力しませんでした。
それはばかげています。ルック カウンターだけでなく、配列の内容をエコーするようにプログラムを再度変更しましょう。
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx];
新しい実行時間は 212 ミリ秒です。そのため、ループ カウンターを単にエコーするよりも、配列の内容にアクセスしてエコーするのに 5% 長くかかりました。
誰かの以前の提案を取り上げて、ループを展開してみましょう。私は過去にこれを C/C++ で非常に効果的に使用しました。
$m = count($x);
for ($idx=0; $idx<$m; $idx+=5) {
echo $x[$idx];
echo $x[$idx+1];
echo $x[$idx+2];
echo $x[$idx+3];
echo $x[$idx+4];
}
今、私たちは話しています!206 ミリ秒まで低下しています。ちょっと待って、これは面白くないコードの約 3% の改善です。そして、出力はひどく見えます。空白などのない数字の文字列です。
ループのアンローリングを取り除き、出力をもう少し良くしましょう:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo "{$x[$idx]}\n";
実行時間は 400 ミリ秒です。は。フォーマットを取得するだけでも、(比較的言えば) 余分な時間がかかります。文字列の置換を使用すると、コストがかかる可能性があります。代わりに文字列連結を試してみましょう:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . "\n";
新しい時間は 390 ミリ秒です。少し良く。数値を改行の代わりにスペースで区切ってみましょう:
$m = count($x);
for ($idx=0; $idx<$m; $idx++)
echo $x[$idx] . " ";
おっと、224 ミリ秒に戻っています。右に!しかし何が起こった?さて、私はこれをすべてUnix端末で実行していますが、数値を別々の行に出力するのは、ラップする1行にすべてを出力するよりも単純に遅くなります。
言い換えれば、端末プログラムのスクロールの速度は、私たちが行った何よりも大きな影響を及ぼします。