【问题标题】:Why is strlen() slower than use of variable when string size does not matter当字符串大小无关紧要时,为什么 strlen() 比使用变量慢
【发布时间】:2013-02-12 14:50:53
【问题描述】:

我正在编写一些简单的文件操作,并且想到如果我将字符串大小保存在变量中不会更快。结果表明它快了 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

【问题讨论】:

  • 最令人惊奇的是 PHP 似乎无法对这个循环应用一些优化。
  • PHP 字符串可以包含空值(例如原始二进制数据),因此标准 C 样式的 strlen 会失败并少报长度。这不是零成本,但 strlen 基本上是一个 O(1) 操作。
  • 300 万个字符串长度的探针真的是您唯一的代码,还是文件保存不是更相关?
  • 当然,函数调用比变量赋值更昂贵,尤其是当变量已经存在并且它的值只是被相同类型的值覆盖时(不需要创建或内存分配)
  • @MarkBaker:它的显示速度慢了 10 倍。并且两个循环中有 3 个不同的变量(size1size2size3)。

标签: php performance strlen


【解决方案1】:

这更符合科林的回答

更有趣的是,我在 str_repeat 调用中输入的数字并不重要,因此 strlen 显然不计算任何东西 - 大小必须保存在某个地方,而 strlen 只是返回值的函数。

这是正确的。在深入研究了源代码一段时间后,我最终得出了这一行:

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

所以是的,strlen 的值被计算一次并被缓存。

【讨论】:

  • 很有趣,感谢您的注意。我已对此 +1 投了票,再次感谢您。
【解决方案2】:

函数调用比变量检索要多得多。每次执行函数时:

  1. 创建了一个新堆栈,并将函数的参数存储在堆栈中。
  2. 在栈上为函数的返回值分配内存
  3. 之前分配的内存地址存放在栈上
  4. 函数的地址被调用
  5. 函数从堆栈中读取参数
  6. 返回值存储在堆栈中
  7. 执行恢复到调用者并清除堆栈

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 2015-11-02
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多