遭遇php的in_array低性能问题_php技巧_脚本之家

2020-01-24 23:18栏目:编程
TAG:

bob体育平台,PHP的性能一直在提高。然而,若是用的不恰当,或是一个不留神,还是可能会踩到PHP内部实现方面的坑的。我在前几天的一个性能问题上就碰到了。 事情是这样子的,一位同事反馈我们的一个接口每次返回需要5秒之久,我们一起review了代码,“惊喜”的发现居然在循环中调用了一个读缓存的操作,而这个缓存的key并没有改变,因此我们把这段代码移到了循环外面,再测,接口返回时间降到了2秒,呜呼!虽然提升了1倍,但明显不是我们能接受的结果! 出现性能问题的代码量并不大,我们排除了IO问题以后,写了一段测试代码,果然问题很快重现。 复制代码 代码如下: shell$ time /usr/local/php/bin/php test.php real 0m1.132s user 0m1.118s sys 0m0.015s 对的,我们用的就是字符串型的数字,从缓存拿出来就是这样子的啦!所以这里是特意转成字符串的(如果直接是数字,并不会出现这个问题 ,各位可以自行验证)。可以看出时间耗掉了1秒,才3000次循环,后面的sys用时也注定我们用strace不会拿到什么有效信息。 shell$ strace -ttt -o xxx /usr/local/php/bin/php test.php shell$ less xxx 我们只看到这两次系统调用之间的延时非常大,却并不知道干了什么?一筹莫展了,幸好,Linux下的调试利器除了strace还有ltrace(当然还有dtrace,ptrace,不在本文讨论范围了,略去)。 引用:strace用来 跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况(via IBM developerworks)。 为了排除干扰因素,我们将$x直接赋值为array的形式,避免过多的malloc调用影响结果。执行 shell$ ltrace -c /usr/local/php/bin/php test.php 如图2我们看到库函数__strtol_bob体育app,internal的调用非常之频繁,达到了94%,太夸张了,然后我又查了一下这个库函数__strtol_internal是干嘛的,原来是strtol的别名,简单的说就是把字符串转换成长整形,可以猜测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:复制代码 代码如下: shell$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php 可以轻松抓到大量下图这样的调用,到此,问题找到了,in_array这种松比较,会将两个字符型数字串先转换为长整型再进行比较,却不知性能就耗在这上面了。知道了症结所在,我们解决的办法就很多了,最简单的就是为in_array加第三个参数为true,即变为严格比较,同时还要比较类型,这样避免了PHP自作聪明的转换类型,跑起来果然快多了,代码如下:

本文实例讲述了使用ltrace工具跟踪PHP库函数调用的方法。分享给大家供大家参考,具体如下:

复制代码 代码如下:

可能大家已经很熟悉使用strace来跟踪系统调用,今天介绍一个跟踪库函数的利器ltrace

for{ if{ continue; }}?>

比如我有这么一段PHP代码

复制代码 代码如下: shell$ time /usr/local/php/bin/php test.php real 0m0.267s user 0m0.247s sys 0m0.020s 快了好多倍啊!!!可以看到sys耗时几乎没有太大变化。我们再次ltrace一把,还是要把$x直接赋值,排除malloc调用的干扰,因为我们实际应用中是从缓存里一次拉出来的,所以也不存在示例代码中这样的循环来申请内存的情况。 再次执行 复制代码 代码如下: shell$ ltrace -c /usr/local/php/bin/php test.php 如下图:

ltrace -c /usr/local/php/bin/php test.php

版权声明:本文由bob体育app发布于编程,转载请注明出处:遭遇php的in_array低性能问题_php技巧_脚本之家