写了一段很简单的代码示例,却发现运行起来速度很慢,出现性能问题的代码量并不大,排除了IO问题以后,写了一段测试代码,果然问题很快重现。 ?php$y="1800";$x = array();for($j=0;$j[root@xp trace]# time php test.phpreal 0m4.116suser 0m4.070ssys 0m0.
写了一段很简单的代码示例,却发现运行起来速度很慢,出现性能问题的代码量并不大,排除了IO问题以后,写了一段测试代码,果然问题很快重现。
<?php $y="1800"; $x = array(); for($j=0;$j [root@xp trace]# time php test.php real 0m4.116s user 0m4.070s sys 0m0.028s
可以看出时间耗掉了4秒,下面用strace跟踪没拿到什么有效信息。
[root@xp trace]# strace -ttt -o log.txt php test.php [root@xp trace]# more log.txt
只看到这两次系统调用之间的延时非常大,却并不知道干了什么?一筹莫展了,幸好,Linux下的调试利器除了strace还有ltrace(当然还有dtrace,ptrace)。
引用:strace用来 跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况(via?IBM developerworks)。
[root@xp trace]# ltrace -c php test.php
我们看到库函数strtol的调用非常之频繁,太夸张了,然后我又查了一下这个库函数,简单的说就是把字符串转换成长整形,可以猜测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:
[root@xp trace]# ltrace -e "strtol" php test.php (0, 0, 0xec4b00, -1, 0x1f25bc2) = 0x32dd221160 strtol(0x1c9f9d0, 0, 10, 0, 0x7fffe64537f0) = 8 strtol(0x1c9f9b0, 0, 10, 0x7fffe6453880, 0x7fffe64537f0) = 30719 strtol(0x1c9f9d0, 0, 10, 0x32ddb8ee88, 0x32ddb8d580) = -9 strtol(0x1c9f070, 0, 10, 371, 0x10119a0) = 0 strtol(0x1c9ea90, 0, 10, 370, 0x10119a0) = 0 strtol(0x1c9e580, 0, 10, 81, 0x1010c60) = 1 strtol(0x1c9fae0, 0, 10, 82, 0x1010c60) = 0 strtol(0x1ca0cf0, 0, 10, 26, 0x1010c60) = 0 strtol(0x1c9f7a0, 0, 10, 408, 0x1010c60) = 0 strtol(0x1c9e6d0, 0, 10, 432, 0x1010c60) = 0 strtol(0xcea563, 0, 10, 433, 0x1010c60) = 0 strtol(0xcea563, 0, 0, 440, 0x1010c60) = 0 strtol(0x1c9f8f0, 0, 0, 72, 0x1010c60) = -1 strtol(0xcea563, 0, 10, 298, 0x1010c60) = 0 strtol(0x1c9ee50, 0, 10, 5, 0x1010c60) = 1 strtol(0x1c9fb80, 0, 10, 83, 0x1010c60) = 1 strtol(0x1c9fc30, 0, 0, 88, 0x1010c60) = 1024 strtol(0x1c9fce0, 0, 10, 96, 0x1010c60) = 0 strtol(0x1c9fd90, 0, 10, 97, 0x1010c60) = 0 strtol(0x1c9f330, 0, 10, 98, 0x1010c60) = 1 strtol(0x1c9e4d0, 0, 10, 461, 0x1010c60) = 0 strtol(0x1ca05a0, 0, 10, 0, 0x1010c60) = 0 strtol(0x1ca0650, 0, 10, 1, 0x1010c60) = 0 strtol(0x1ca0700, 0, 10, 2, 0x1010c60) = 0 strtol(0x1c9ec70, 0, 0, 8, 0x1010c60) = 0 strtol(0x1ca03c0, 0, 10, 411, 0x1010c60) = 1 strtol(0x1ca0260, 0, 10, 409, 0x1010c60) = 0 strtol(0x1ca0310, 0, 10, 410, 0x1010c60) = 0 strtol(0x1ca0460, 0, 10, 412, 0x1010c60) = 1 strtol(0x1c9f130, 0, 10, 3, 0x1010c60) = 0 strtol(0x1c9f1d0, 0, 10, 24, 0x1010c60) = 0 strtol(0x1c9e9f0, 0, 10, 369, 0x10119a0) = 1 strtol(0x1c9feb0, 0, 10, 25, 0x1010c60) = 0 strtol(0x1c9f3d0, 0, 10, 80, 0x1010c60) = 0 strtol(0x1c9ebd0, 0, 10, 413, 0x1010c60) = 1 strtol(0x1c9efe0, 0, 0, 48, 0x1010c60) = 17 strtol(0x1c9f850, 0, 10, 0, 0) = 0 strtol(0x1ca0d90, 0, 10, 457, 0x1010c60) = 1 strtol(0x1ca0e40, 0, 0, 160, 0x1010c60) = 1000 strtol(0x1ca0500, 0, 0, 432, 0x1010ec0) = 1000 strtol(0xd214c5, 0, 0, 520, 0x1010c60) = 64 strtol(0xd37961, 0, 0, 584, 0x1010c60) = 1000 strtol(0x1ca1250, 0, 10, 560, 0x1010c60) = 1 strtol(0x1c9f990, 0, 0, 0, 0) = 512 strtol(0x1c9eb30, 0, 10, 0, 0) = 14 strtol(0x1ca0f80, 0, 10, 459, 0x1010c60) = 1 strtol(0x1ca1030, 0, 10, 512, 0x1010c60) = 0 strtol(0xcea563, 0, 10, 460, 0x1010c60) = 0 strtol(0xd37a32, 0, 0, 24, 0x100ec20) = 16 strtol(0xd37a49, 0, 0, 32, 0x100ec20) = 120 strtol(0xd37a7c, 0, 0, 544, 0x1010c60) = 300 strtol(0xcea563, 0, 10, 513, 0x1010c60) = 0 strtol(0x1c9ef30, 0, 10, 0, 0) = 30711 strtol(0x1c9f700, 0, 10, 0, 0x1011d80) = 1 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 531783 (0, 0, 0, 15, 0x42622d0) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 531720 (0, 0, 0, 11, 0x7f9fa7b51b80) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 531719 (0, 0, 0, 6, 0x9275f60) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 531897 (0, 0, 0, 9, 0x7f9fa74b8338) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 531901 (0, 0, 0, 3, 0x7f9fa72a8340) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 532944 (0, 0, 0, 3, 0x7f9fa70641d0) = 0x32dd221160 (0x32dd221160, 0, 0, 0x32dd221160, 0) = 525536 (0, 0, 0, 3, 0x7f9fa6e5c680) = 0x32dd221160 .....
知道了症结所在,我们解决的办法就很多了,最简单的就是为in_array加第三个参数为true,即变为严格比较,同时还要比较类型,这样避免了PHP自作聪明的转换类型,跑起来果然快多了。
[root@xp trace]# time php test.php real 0m0.988s user 0m0.959s sys 0m0.024s写了一段很简单的代码示例,却发现运行起来速度很慢,出现性能问题的代码量并不大,排除了IO问题以后,写了一段测试代码,果然问题很快重现。 可以看出时间耗掉了4秒,下面用strace跟踪没拿到什么有效信息。 只看到这两次系统调用之间的延时非常大,却并不知道干了什么?一筹莫展了,幸好,Linux下的调试利器除了strace还有ltrace(当然还有dtrace,ptrace)。 引用:strace用来 跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况(via?IBM developerworks)。 我们看到库函数strtol的调用非常之频繁,太夸张了,然后我又查了一下这个库函数,简单的说就是把字符串转换成长整形,可以猜测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行: 知道了症结所在,我们解决的办法就很多了,最简单的就是为in_array加第三个参数为true,即变为严格比较,同时还要比较类型,这样避免了PHP自作聪明的转换类型,跑起来果然快多了。