关于在str_replace前先strpos能提升效能的实际测试

来源:互联网 发布:机器视觉算法选择 编辑:程序博客网 时间:2024/05/10 23:38

网上流行一些关于执行代码效率的内容,实际测试了一下,有一些结果并非像内容中提及的那样

比如有人建议在str_replace前先用strpos进行查找操作,理由是即使没有替换,str_replace 也会为其参数分配内存从而很慢,因此需要用 strpos 先查找,看是否需要替换,如果需要,再替换
其文中给出的效率提升是:
- 如果需要替换:效率几乎相等,差别在 0.1% 左右。
- 如果不需要替换:用 strpos 快 200%。

这跟我实测的结果并不相同.

  1. <?php
  2. $a=<<<EOT
  3. 提高php代码的效率2收藏
  4. 新一篇: php程序员容易犯的10个错误 | 旧一篇: PHP代码优化
  5. 这篇杂文翻译整理自网络各路文档资料(见最末的参考资料),尤其是 Ilia Alshanetsky (佩服之至) 在多个 PHP 会议上的演讲,主要是各类提高 PHP 性能的技巧。为求精准,很多部分都有详细的效率数据,以及对应的版本等等。偷懒,数据就不一一给出了,直接给结论,如果需要看原文档,请到文末「参考资料」部分。橙色标题为推荐部分。
  6. ========================================================
  7. 静态调用的成员一定要定义成 static  (PHP5 ONLY)
  8. 贴士:PHP 5 引入了静态成员的概念,作用和 PHP 4 的函数内部静态变量一致,但前者是作为类的成员来使用。静态变量和 Ruby 的类变量(class variable)差不多,所有类的实例共享同一个静态变量。
  9. 静态地调用非 static 成员,效率会比静态地调用 static 成员慢 50-60%。主要是因为前者会产生 E_STRICT 警告,内部也需要做转换。
  10. 使用类常量 (PHP5 ONLY)
  11. 贴士:PHP 5 新功能,类似于 C++ 的 const
  12. 使用类常量的好处是:
  13. - 编译时解析,没有额外开销
  14. - 杂凑表更小,所以内部查找更快
  15. - 类常量仅存在于特定「命名空间」,所以杂凑名更短
  16. - 代码更干净,使除错更方便
  17. (暂时)不要使用 require/include_once 
  18. require/include_once 每次被调用的时候都会打开目标文件!
  19. - 如果用绝对路径的话,PHP 5.2/6.0 不存在这个问题
  20. - 新版的 APC 缓存系统已经解决这个问题
  21. 文件 I/O 增加 => 效率降低
  22. 如果需要,可以自行检查文件是否已被 require/include
  23. 不要调用毫无意义的函数
  24. 有对应的常量的时候,不要使用函数。
  25. 虽然使用不多,但是效率提升大概在 3500% 左右。
  26. 最快的 Win32 检查
  27. - 不用函数
  28. - Win98/NT/2000/XP/Vista/Longhorn/Shorthorn/Whistler...通用
  29. - 一直可用
  30. 时间问题 (PHP>5.1.0 ONLY)
  31. 你如何在你的软件中得知现在的时间?简单,「time() time() again, you ask me...」。
  32. 不过总归会调用函数,慢。
  33. 现在好了,用 ,不用调用函数,又省了。
  34. 加速 PCRE
  35. - 对于不用保存的结果,不用 (),一律用 (?:)
  36. 这样 PHP 不用为符合的内容分配内存,省。效率提升 15% 左右。
  37. - 能不用正则,就不用正则,在分析的时候仔细阅读手册「字符串函数」部分。有没有你漏掉的好用的函数?
  38. 例如:
  39. strpbrk()
  40. strncasecmp()
  41. strpos()/strrpos()/stripos()/strripos()
  42. 加速 strtr
  43. 如果需要转换的全是单个字符的时候,用字符串而不是数组来做 strtr
  44. 效率提升:10 倍。
  45. 不要做无谓的替换
  46. 即使没有替换,str_replace 也会为其参数分配内存。很慢!解决办法:
  47. - 用 strpos 先查找(非常快),看是否需要替换,如果需要,再替换
  48. 效率:
  49. - 如果需要替换:效率几乎相等,差别在 0.1% 左右。
  50. - 如果不需要替换:用 strpos 快 200%。
  51. 邪恶的 @ 操作符
  52. 不要滥用 @ 操作符。虽然 @ 看上去很简单,但是实际上后台有很多操作。用 @ 比起不用 @,效率差距:3 倍。
  53. 特别不要在循环中使用 @,在 5 次循环的测试中,即使是先用 error_reporting(0) 关掉错误,在循环完成后再打开,都比用 @ 快。
  54. 善用 strncmp
  55. 当需要对比「前 n 个字符」是否一样的时候,用 strncmp/strncasecmp,而不是 substr/strtolower,更不是 PCRE,更千万别提 eregstrncmp/strncasecmp 效率最高(虽然高得不多)。
  56. EOT;
  57. $start_time=array_sum(explode(" ",microtime()));
  58. for($i=0;$i<10000;$i++)
  59. {
  60.   if(strPos($a,'strncmp')) str_replace("strncmp","",$a);
  61. }
  62. echo $Runtime="runtime:".((array_sum(explode(" ",microtime()))-$start_time)*1000)."ms";
  63. ?>

实际测试下来,在满足替换条件的情况下,

执行Strpos时间是178ms,直接str_replace是113ms.

在不满足替换条件下,strpos加上后是72ms,不加是88ms

由此数据看出.综合而言使用strpos在大多数需要替换的情况下会加大系统开销.并不是一个值得提倡的作法 :-(

原创粉丝点击