2

簡単なファイル操作を書いていて、文字列のサイズを変数に保存すると速くならないのではないかと考えました。10倍高速であることがわかりました。
このコードの使用:

include "../classes/Timer.class.php";
$t = new Timer();             //Timer class I've written for this purpose [link below]
$multiplyer = 3000000;        //Times to try the operation
$string = str_repeat("ggggggggggg",2);  //I first tried 2000 here, but for 2 there are same results
$t("calling");     //Saving time
for($i=0; $i<$multiplyer; $i++) {
  $size =  strlen($string);
  $size2 = strlen($string);
  $size3 = strlen($string);
}
$t("clover");
$t("caching");     //Saving time
for($i=0; $i<$multiplyer; $i++) {
  $size =  strlen($string);
  $size2 = $size;
  $size3 = $size;
}
$t("chover");
$total = $t["calling-clover"]+$t["caching-chover"];  //percents are usefull :)
echo "Calling: {$t["calling-clover"]} (".round(($t["calling-clover"]/$total)*100)."%)<br>\n";
echo "Caching in variables: {$t["caching-chover"]} (".round(($t["caching-chover"]/$total)*100)."%)<br>\n";

結果:

呼び出し: 1.988455057 (67%)
変数へのキャッシュ: 0.984993458 (33%)

さらに興味深いのは、str_repeat呼び出しに入力した数値は問題ではないため、 はstrlen明らかに何も計算しないという事実です。サイズはどこかに保存する必要があり、strlen値を返す関数にすぎません。
これは次のことを意味します:
関数呼び出しは本当に遅いのでしょうか?
そうでない場合、これはstrlen特定のものですか?


タイマー.class.php

4

2 に答える 2

8

これは、コリンの答えをより褒めたたえています

さらに興味深いのは、str_repeat 呼び出しに入力した数値は問題ではないため、strlen は明らかに何も計算しないという事実です。サイズはどこかに保存する必要があり、strlen は値を返す関数にすぎません。

正解です。かなり長い間ソースを調べた後、次の行にたどり着きました:

#define Z_STRLEN(zval)                  (zval).value.str.len

そうです、strlen の値は一度計算されてキャッシュされます。

于 2013-02-12T15:15:24.000 に答える
4

関数呼び出しには、変数の取得以外にも多くの機能があります。関数を実行するたびに:

  1. 新しいスタックが作成され、関数への引数がスタックに格納されます。
  2. 関数の戻り値用にスタックにメモリが割り当てられます
  3. 以前に割り当てられたメモリ アドレスがスタックに格納されます。
  4. 関数のアドレスが呼び出されます
  5. 関数はスタックから引数を読み取ります
  6. 戻り値はスタックに格納されます
  7. 実行が呼び出し元に復元され、スタックがクリアされます
于 2013-02-12T14:59:23.797 に答える