在调试基于Symfony的项目的性能问题时,我注意到执行堆栈的某些部分会浪费大量CPU时间。一分钟后,发现了嫌疑人。是gzdelfate($serializedObject, 9)。
该函数是ZLIB库的一部分,例如,当您要压缩/解压缩字符串时,最常用于PHP项目中,例如,在将缓存条目发送到Redis。
首先想法,压缩水平设置为9,这是最大值,应降低以减少CPU时间的消耗。但是如何找到一个甜蜜的地方呢?谷歌搜索没有回答我的问题。因此,我决定编写一个可以用不同级别进行基准压缩/解压缩的脚本。
基准
通过php-zlib扩展的gzdeflate和gzinflate功能,获得了以下结果。基准已在Amazon EC2 C5.Xlarge实例上使用PHP 7.4.33启动。 C5实例建立在3.0 GHz Intel Xeon可伸缩(Skylake)处理器上,并有可能使用Intel Turbo Boost Technology以高达3.5 GHz的速度运行。
其他ZLIB压缩函数的基准Gzencode和GZCompress与GZDeflate没有什么不同。
压缩水平 | 压缩速度,MB/S | 减压速度,mb/s | 比率 | 节省空间,% | 比率 /时间< / th> |
---|---|---|---|---|---|
1 | 137.16 | 64.41 | 7.4 | 86.6 | 2246.223 |
2 | 131.49 | 63.84 | 7.8 | 87.1 | 2246.826 |
3 | 115.43 | 60.84 | 8.0 | 87.5 | 2039.500 |
4 | 90.59 | 59.36 | 8.8 | 88.7 | 1764.139 |
5 | 79.66 | 58.89 | 9.5 | 89.4 | 1661.567 |
6 | 57.36 | 58.92 | 10.0 | 90.0 | 1265.741 |
7 | 48.05 | 58.22 | 10.1 | 90.1 | 1069.743 |
8 | 29.67 | 57.38 | 10.2 | 90.2 | 669.068 |
9 | 27.99 | 56.54 | 10.2 | 90.2 | 631.573 |
结论
运行数百个具有不同文件大小和内容类型的测试(例如序列化对象,HTML,纯文本)表明,高压缩液位在节省空间方面并没有很大差异,但在CPU时间方面非常昂贵。例如,压缩级别9的2.4 MB大型序列化对象的压缩为69.90毫秒,压缩文件大小为212 kb。 6级(默认值)为37.23 ms,压缩文件大小为217 kb。 2级压缩将需要17.59毫秒,压缩文件大小为228 kb。假设缓存存储在REDIS中,我们要考虑到通过网络传输额外数量的信息的时间。通过10 Gbps带宽的网络将额外的16 KB(228-212)转移将小于1 ms。
您可以找到here的更多详细信息。
这也解释了为什么NGINX默认使用级别1使用1级,而偏爱更高的速度,而不是文件大小节省。
i将压缩比与压缩时间(最后一列)所花费的时间的比率定义为黄金平均值。价值越高,越好。但这取决于手头的任务。如果您的应用程序存储了压缩数据的Terabytes,则压缩水平为9可能是合适的。另一方面,如果您的目标是高性能,则级别2和3会做。
该分析的结果是,通过更改代码中的一位数字,该站点的速度比以前快16%。平均CPU使用量减少了58%。
如果这篇文章对某人很有用,我可以编写第二部分,以比较压缩算法的现代实现,例如ZSTD,Brotli,Snappy和LZ4。