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