返回首页

PHP性能分析相关的函数

此前,阅读过了很多关于PHP性能分析的文章,不过写的都是一条一条的规则,而且,这些规则并没有上下文,也没有明确的实验来体现出这些规则的优势,同时讨论的也侧重于一些语法要点。本文就改变PHP性能分析的角度,并通过实例来分析出PHP的性能方面需要注意和改进的点。

在开始分析之前,我们得掌握一些与性能分析相关的函数。这些函数让我们对程序性能有更好的分析和评测。

一、性能分析相关的函数与命令

1.1、时间度量函数

平时我们常用time()函数,但是返回的是秒数,对于某段代码的内部性能分析,到秒的精度是不够的。于是要用microtime函数。而microtime函数可以返回两种形式,一是字符串的形式,一是浮点数的形式。不过需要注意的是,在缺省的情况下,返回的精度只有4位小数。为了获得更高的精确度,我们需要配置precision。

如下是microtime的使用结果。

$start=microtime(true);echo$start.\n;$end=microtime(true);echo$end.\n;echo($end-$start).\n;

输出为:

bash-3.2#phptime.php

.

.

0.

而在代码前面加上一行:

ini_set(precision,16);

输出为:

bash-3.2#phptime.php

.

.

0.

除了microtime内部统计之外,还可以使用getrusage来取得用户态的事长。在实际的操作中,也常用time命令来计算整个程序的运行时长,通过多次运行或者修改代码后运行,得到不同的时间长度以得到效率上的区别。具体用法是:timephptime.php,则在程序运行完成之后,不管是否正常结束退出,都会有相关的统计。

bash-3.2#timephptime.php

.

.

0.

real0m0.s

user0m0.s

sys0m0.s

因为本文所讨论的性能问题,往往分析上百万次调用之后的差距与趋势,为了避免代码中存在一些时间统计代码,后面我们使用time命令居多。

1.2、内存使用相关函数

分析内存使用的函数有两个:memory_get_usage、memory_get_peak_usage,前者可以获得程序在调用的时间点,即当前所使用的内存,后者可以获得到目前为止高峰时期所使用的内存。所使用的内存以字节为单位。

$base_memory=memory_get_usage();echoHello,world!\n;$end_memory=memory_get_usage();$peak_memory=memory_get_peak_usage();echo$base_memory,\t,$end_memory,\t,($end_memory-$base_memory),\t,$peak_memory,\n;

输出如下:

bash-3.2#phphelloworld.php

Hello,world!

可以看到,即使程序中间只输出了一句话,再加上变量存储,也消耗了个字节的内存。

对于同一程序,不同PHP版本对内存的使用并不相同,甚至还差别很大。

$baseMemory=memory_get_usage();classUser{private$uid;function__construct($uid){$this-uid=$uid;}}for($i=0;$i;$i++){$obj=newUser($i);if($i%===0){echosprintf(%6d:,$i),memory_get_usage(),bytes\n;}}echopeak:,memory_get_peak_usage(true),bytes\n;

在PHP5.2中,内存使用如下:

[root

localhostphpperf]#php52memory.php

0:bytes

:bytes

……:bytes

:bytes

peak:bytes

PHP5.3中,内存使用如下

[root

localhostphpperf]#phpmemory.php

0:bytes

:bytes

……:bytes

:bytes

peak:bytes

可见PHP5.3在内存使用上要粗放了一些。

PHP5.4-5.6差不多,有所优化:

[root

localhostphpperf]#php56memory.php

0:bytes

:bytes

……:bytes

:bytes

peak:bytes

而PHP7在少量使用时,高峰内存的使用,增大很多。

[root

localhostphpperf]#php7memory.php

0:bytes

:bytes

……:bytes

:bytes

peak:bytes

从上面也看到,以上所使用的PHP都有比较好的垃圾回收机制,10万次初始化,并没有随着对象初始化的增多而增加内存的使用。PHP7的高峰内存使用最多,达到了接近2M。

下面再来看一个例子,在上面的代码的基础上,我们加上一行,即如下加粗的一行:

$obj-self=$obj;

代码如下:

$baseMemory=memory_get_usage();classUser{private$uid;function__construct($uid){$this-uid=$uid;}}for($i=0;$i;$i++){$obj=newUser($i);$obj-self=$obj;if($i%===0){echosprintf(%6d:,$i),memory_get_usage(),bytes\n;}}echopeak:,memory_get_peak_usage(true),bytes\n;

这时候再来看看内存的使用情况,中间表格主体部分为内存使用量,单位为字节。

图表如下:

PHP5.2并没有合适的垃圾回收机制,导致内存使用越来越多。而5.3以后内存回收机制导致内存稳定在一个区间。而也可以看见PHP7内存使用最少。把PHP5.2的图形去掉了之后,对比更为明显。

可见PHP7不仅是在算法效率上,有大幅度的提升,在大批量内存使用上也有大幅度的优化(尽管小程序的高峰内存比历史版本所用内存更多)。

1.3、垃圾回收相关函数

在PHP中,内存回收是可以控制的,我们可以显式地关闭或者打开垃圾回收,一种方法是通过修改配置,zend.enable_gc=Off就可以关掉垃圾回收。缺省情况下是On的。另外一种手段是通过gc_enable()和gc_disable()函数分别打开和关闭垃圾回收。

比如在上面的例子的基础上,我们关闭垃圾回收,就可以得到如下数据表格和图表。

代码如下:

gc_disable();$baseMemory=memory_get_usage();classUser{private$uid;function__construct($uid){$this-uid=$uid;}}for($i=0;$i;$i++){$obj=newUser($i);$obj-self=$obj;if($i%===0){echosprintf(%6d:,$i),memory_get_usage(),bytes\n;}}echopeak:,memory_get_peak_usage(true),bytes\n;

分别在PHP5.3、PHP5.4、PHP5.5、PHP5.6、PHP7下运行,得到如下内存使用统计表。

图表如下,PHP7还是内存使用效率最优的。

从上面的例子也可以看出来,尽管在第一个例子中,PHP7的高峰内存使用数是最多的,但是当内存使用得多时,PHP7的内存优化就体现出来了。

这里值得一提的是垃圾回收,尽管会使内存减少,但是会导致速度降低,因为垃圾回收也是需要消耗CPU等其他系统资源的。Composer项目就曾经因为在计算依赖前关闭垃圾回收,带来成倍性能提升,引发广大网友







































广州治疗白癜风最好的专科医院
江苏白癜风医院

版权所有:Copyright ? 2012-12-20 php发展_php应用_php开发

电话:

当前时间: