PHP性能分析相關的函數

此前,閱讀過了不少關於 PHP 性能分析的文章,不過寫的都是一條一條的規則,並且,這些規則並無上下文,也沒有明確的實驗來體現出這些規則的優點,同時討論的也側重於一些語法要點。本文就改變 PHP 性能分析的角度,並經過實例來分析出 PHP 的性能方面須要注意和改進的點。php

 

在開始分析以前,咱們得掌握一些與性能分析相關的函數。這些函數讓咱們對程序性能有更好的分析和評測。git

 

1、性能分析相關的函數與命令github

 

1.一、時間度量函數算法

 

平時咱們經常使用 time() 函數,可是返回的是秒數,對於某段代碼的內部性能分析,到秒的精度是不夠的。因而要用 microtime 函數。而 microtime 函數能夠返回兩種形式,一是字符串的形式,一是浮點數的形式。不過須要注意的是,在缺省的狀況下,返回的精度只有4位小數。爲了得到更高的精確度,咱們須要配置 precision。小程序

 

以下是 microtime 的使用結果。bash

 

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

輸出爲:php7

 

bash-3.2# phptime.phpcomposer

1441360050.3286 函數

1441360050.3292 性能

0.00053000450134277

 

而在代碼前面加上一行:

 

ini_set("precision", 16);

輸出爲:

 

bash-3.2# phptime.php

1441360210.932628

1441360210.932831

0.0002031326293945312

 

除了 microtime 內部統計以外, 還可使用 getrusage 來取得用戶態的事長。在實際的操做中,也經常使用 time 命令來計算整個程序的運行時長,經過屢次運行或者修改代碼後運行,獲得不一樣的時間長度以獲得效率上的區別。 具體用法是:time phptime.php ,則在程序運行完成以後,不論是否正常結束退出,都會有相關的統計。

 

bash-3.2# time phptime.php

 

1441360373.150756

1441360373.150959

0.0002031326293945312

 

real 0m0.186s

user 0m0.072s

sys 0m0.077s

 

由於本文所討論的性能問題,每每分析上百萬次調用以後的差距與趨勢,爲了不代碼中存在一些時間統計代碼,後面咱們使用 time 命令居多。

 

1.二、內存使用相關函數

 

分析內存使用的函數有兩個:memory_ get_ usage、memory_ get_ peak_usage,前者能夠得到程序在調用的時間點,即當前所使用的內存,後者能夠得到到目前爲止高峯時期所使用的內存。所使用的內存以字節爲單位。

 

$base_memory= memory_get_usage();
echo "Hello,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!

224400 224568 168 227424

 

能夠看到,即便程序中間只輸出了一句話,再加上變量存儲,也消耗了168個字節的內存。

 

對於同一程序,不一樣 PHP 版本對內存的使用並不相同,甚至還差異很大。

 

$baseMemory= memory_get_usage();
class User
{
private $uid;
function __construct($uid)
    {
$this->uid= $uid;
    }
}

for($i=0;$i<100000;$i++)
{
$obj= new User($i);
if ( $i% 10000 === 0 )
    {
echo sprintf( '%6d: ', $i), memory_get_usage(), " bytes\n";
    }
}
echo "  peak: ",memory_get_peak_usage(true), " bytes\n";

 

在 PHP 5.2 中,內存使用以下:

 

[root@localhostphpperf]# php52 memory.php

 

0: 93784 bytes

10000: 93784 bytes

…… 80000: 93784 bytes

90000: 93784 bytes

peak: 262144 bytes

 

PHP 5.3 中,內存使用以下

 

[root@localhostphpperf]# phpmemory.php

 

0: 634992 bytes

10000: 634992 bytes

…… 80000: 634992 bytes

90000: 634992 bytes

peak: 786432 bytes

 

可見 PHP 5.3 在內存使用上要粗放了一些。

 

PHP 5.4 - 5.6 差很少,有所優化:

 

[root@localhostphpperf]# php56 memory.php

 

0: 224944 bytes

10000: 224920 bytes

…… 80000: 224920 bytes

90000: 224920 bytes

peak: 262144 bytes

 

而 PHP 7 在少許使用時,高峯內存的使用,增大不少。

 

[root@localhostphpperf]# php7 memory.php

 

0: 353912 bytes

10000: 353912 bytes

…… 80000: 353912 bytes

90000: 353912 bytes

peak: 2097152 bytes

 

從上面也看到,以上所使用的 PHP 都有比較好的垃圾回收機制,10萬次初始化,並無隨着對象初始化的增多而增長內存的使用。PHP7 的高峯內存使用最多,達到了接近 2M。

 

下面再來看一個例子,在上面的代碼的基礎上,咱們加上一行,即以下加粗的一行:

 

$obj->self = $obj;

代碼以下:

 

$baseMemory= memory_get_usage();
class User
{
private $uid;
function __construct($uid)
    {
$this->uid= $uid;
    }
}

for($i=0;$i<100000;$i++)
{
$obj= new User($i);
$obj->self = $obj;
if ( $i% 5000 === 0 )
    {
echo sprintf( '%6d: ', $i), memory_get_usage(), " bytes\n";
    }
}
echo "  peak: ",memory_get_peak_usage(true), " bytes\n";

 

這時候再來看看內存的使用狀況,中間表格主體部分爲內存使用量,單位爲字節。

圖表以下:

 

PHP 5.2 並無合適的垃圾回收機制,致使內存使用愈來愈多。而5.3 之後內存回收機制致使內存穩定在一個區間。而也能夠看見 PHP7 內存使用最少。把 PHP 5.2 的圖形去掉了以後,對比更爲明顯。

 

 

可見 PHP7 不只是在算法效率上,有大幅度的提高,在大批量內存使用上也有大幅度的優化(儘管小程序的高峯內存比歷史版本所用內存更多)。

 

1.三、垃圾回收相關函數

 

在 PHP 中,內存回收是能夠控制的,咱們能夠顯式地關閉或者打開垃圾回收,一種方法是經過修改配置,zend.enable_gc=Off 就能夠關掉垃圾回收。缺省狀況下是 On 的。另一種手段是經過 gc _enable()和gc _disable()函數分別打開和關閉垃圾回收。

 

好比在上面的例子的基礎上,咱們關閉垃圾回收,就能夠獲得以下數據表格和圖表。

 

代碼以下:

 

gc_disable();
$baseMemory= memory_get_usage();
class User
{
private $uid;
function __construct($uid)
    {
$this->uid= $uid;
    }
}

for($i=0;$i<100000;$i++)
{
$obj= new User($i);
$obj->self = $obj;
if ( $i% 5000 === 0 )
    {
echo sprintf( '%6d: ', $i), memory_get_usage(), " bytes\n";
    }
}
echo "  peak: ",memory_get_peak_usage(true), " bytes\n";

分別在 PHP 5.三、PHP5.4 、PHP5.五、PHP5.6 、PHP7 下運行,獲得以下內存使用統計表。

 

 

圖表以下,PHP7 仍是內存使用效率最優的。

 

從上面的例子也能夠看出來,儘管在第一個例子中,PHP7 的高峯內存使用數是最多的,可是當內存使用得多時,PHP7 的內存優化就體現出來了。

 

這裏值得一提的是垃圾回收,儘管會使內存減小,可是會致使速度下降,由於垃圾回收也是須要消耗 CPU 等其餘系統資源的。Composer 項目就曾經由於在計算依賴前關閉垃圾回收,帶來成倍性能提高,引起廣大網友關注。詳見:

 

https://github.com/composer/composer/commit/ac676f47f7bbc619678a29deae097b6b0710b799

 

在常見的代碼和性能分析中,出了以上三類函數以外,還常使用的有堆棧跟蹤函數、輸出函數,這裏再也不贅述。

相關文章
相關標籤/搜索