php-8.0.0 性能測試


測試環境為 apple m1
測試的 php 版本為 8.0.0, 對比的版本為 7.2.34,golang 1.15.6 amd64 with rosetta 2
php 通過 homebrew 安裝,當前 homebrew 已經支持 apple m1。
golang 為官網下載的安裝包。

測試結果如表格中所示:

語言 耗時 性能分數(越高越好)
php-8.0.0 2.3733 4.17
php-8.0.0 with opcache enabled 2.0988 4.72
php-7.2.34 2.8660 3.46
php-7.2.34 with opcache enabled 2.5066 3.95
golang-1.15.6 am64 with rosetta2 0.0637 155.55

golang 無疑擁有最快的性能。因此目前來看,就算有 jit 加持,php 依然是和性能沒有什么關系的一種工具。

 

測試過程

考慮到 jit 的特性,對重復執行的代碼敏感,對 IO 不敏感,我實現了一段快排算法來測試,快排的 partition 函數會被反復執行,正好考驗 JIT 的效能。

 1 function qsort(&$nums, $from, $to) {
 2     if ($from >= $to)
 3         return;
 4     $mid = partition($nums, $from, $to);
 5     qsort($nums, $from, $mid - 1);
 6     qsort($nums, $mid + 1, $to);
 7 }
 8 
 9 function partition(&$nums, $from, $to) {
10     $pivot = $nums[$from];
11     $i = $from + 1;
12     $j = $to;
13     while (true) {
14         while ($i < $to && $nums[$i] < $pivot) {
15             $i++;
16         }
17 
18         while ($j > $from && $nums[$j] > $pivot) {
19             $j--;
20         }
21 
22         if ($i >= $j) {
23             break;
24         }
25 
26         $t = $nums[$i];
27         $nums[$i] = $nums[$j];
28         $nums[$j] = $t;
29 
30         $i++;
31         $j--;
32     }
33 
34     $t = $nums[$j];
35     $nums[$j] = $pivot;
36     $nums[$from] = $t;
37 
38     return $j;
39 }

 


我用程序實現生成了幾個隨機亂序后的數字的文本文件,num-10.txt 即表示文件內包含 10 個亂序后的數字。生成程序在文末附錄中列出。
因為 apple m1 非常快,我需要 100 萬個數字。
運行 php-8.0.0:
$ php8 qsort.php num-100w.txt
JIT is disabled
time cost: 2.3733279705048


因為 jit 僅支持 x86 平台,因此 JIT 無法在 apple m1 上打開,但即使只打開 opcache,也會看到有性能提升:
$ php8 -d opcache.enable_cli -d opcache.jit_buffer_size=100m -d opcache.jit=1255 qsort.php num-100w.txt
JIT is disabled
time cost: 2.0988318920135


使用 php-7.2.34 運行:
$ php qsort.php num-100w.txt
JIT is disabled
time cost: 2.8660459518433


使用 php-7.2.34 with opcache
$ php -d opcache.enable_cli qsort.php num-100w.txt
JIT is disabled
time cost: 2.5065989494324

golang 的版本如下

func qsort(nums []int, lo int, hi int) {
    if lo >= hi {
        return;
    }
    mid := partition(nums, lo, hi);
    qsort(nums, lo, mid - 1);
    qsort(nums, mid + 1, hi);
}

func partition(nums []int, lo int, hi int) int {
    i := lo + 1;
    j := hi;
    pivot := nums[lo];
    for {
        for (i < hi && nums[i] < pivot) {
            i++;
        }
        for (j > lo && nums[j] > pivot) {
            j--;
        }
        if (i >= j) {
            break;
        }
        nums[i], nums[j] = nums[j], nums[i];
        i++;
        j--;
    }
    nums[lo], nums[j] = nums[j], nums[lo];
    return j;
}

 


golang 用時是令人發指的少:
$ go run qsort.go num-100w.txt
time cost 0.063744


為了試驗 php-8.0 打開 JIT 后的效果,我找來了一台 x86 的雲服務器試驗,這台雲服比 apple m1 性能差很多。
關閉 JIT
JIT is disabled
time cost: 31.630923986435


打開 JIT
JIT is enabled
time cost: 13.33647108078

x86 上打開 JIT 能有顯著的提升 57.8% 的性能提升。
但盡管如此,php 依然和性能不搭嘎,追求性能還是要用更適合的工具。

 

 

附錄-1

隨機數生成工具

 使用方法:python3 gen-nums.py <亂序數字的個數>

例如:python3 gen-nums.py 1000000 > num-1m.txt # 生成 100 萬個亂序的數字

 1 import random
 2 import sys
 3 
 4 DEFAULT_BOUND = 100
 5 
 6 if len(sys.argv) < 2:
 7     print('default num of 100 is used', file=sys.stderr)
 8     bound = DEFAULT_BOUND
 9 else:
10     bound = int(sys.argv[1])
11     if bound <= 3:
12         raise ValueError('must > 3')
13     print('{0} nums will be generated'.format(bound), file=sys.stderr)
14 
15 nums = list(range(1, bound + 1))
16 random.shuffle(nums)
17 for n in nums[0:-1]:
18     print(n, end = ', ')
19 
20 print(nums[-1:][0])

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM