源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

遭遇php的in_array低性能问题

  • 时间:2020-02-27 14:56 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:遭遇php的in_array低性能问题
PHP的性能一直在提高。然而,若是用的不恰当,或是一个不留神,还是可能会踩到PHP内部实现方面的坑的。我在前几天的一个性能问题上就碰到了。 事情是这样子的,一位同事反馈我们的一个接口每次返回需要5秒之久,我们一起review了代码,“惊喜”的发现居然在循环(大约900次)中调用了一个读缓存的操作,而这个缓存的key并没有改变,因此我们把这段代码移到了循环外面,再测,接口返回时间降到了2秒,呜呼!虽然提升了1倍,但明显不是我们能接受的结果! 出现性能问题的代码量并不大,我们排除了IO问题以后,写了一段测试代码,果然问题很快重现。
[url=http://www.ibm.com/developerworks/cn/linux/l-tsl/]IBM developerworks[/url])。 为了排除干扰因素,我们将$x直接赋值为array(“0″,”1″,”2″,……)的形式,避免过多的malloc调用影响结果。执行 shell$ ltrace -c /usr/local/php/bin/php test.php 如图2 [img]http://files.jb51.net/file_images/article/201309/2013091715532521.png[/img] 我们看到库函数__strtol_internal的调用非常之频繁,达到了94%,太夸张了,然后我又查了一下这个[url=http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/baselib---strtol-internal-1.html]库函数__strtol_internal是干嘛的[/url],原来是[url=http://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html]strtol[/url]的别名,简单的说就是把字符串转换成长整形,可以猜测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:
[url=http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/libutil---ctype-tolower-loc.html]库函数__ctype_tolower_loc是干嘛的[/url]:简单的理解是将字符串转换成小写,那么这说明in_array比较字符串不区分大小写吗?其实这个函数调用已经和我们这个in_array感觉联系不大了,关于in_array的实现,还是去看看PHP的源码,大概理解的更为透彻了,好了,没法往下说了,欢迎与我交流,写的不对的地方请多多斧正。 ———————2013.08.29分割线—————————— 晚上又翻了以下PHP 5.4.10的源码,对in_array的兴趣真大啊,哈哈,位于./ext/standard/array.c的第1248行,可以看到他调用了php_search_array函数,下面的array_serach也是调的这个,只是最后一个参数不同!经过一番跟踪,在in_array松比较的情况下,他最终调用的函数 zendi_smart_strcmp(果然是个“聪明”函数)进行比较,位于./Zend/zend_operators.c,我们用ltrace抓到的大量转换成整型的操作就是那个is_numeric_string_ex的行为。 [img]http://files.jb51.net/file_images/article/201309/2013091715532524.png[/img] 函数is_numeric_string_ex是在./Zend/zend_operators.h中定义的,在前面进行了一堆的判断和转换之后,在232行调用了strtol,就是我们在文章中提到的系统函数了,将字符串转换成长整型,有图有真相 [img]http://files.jb51.net/file_images/article/201309/2013091715532525.png[/img]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部