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具体的吗?


Timer.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 回答