php压缩算法对比研究
概要
本文对比了php的各种压缩工具的解压缩速度,试图找出在性能和时间上更具有性价比的工具。具体包括:
- gzencode/gzdecode
- gzdeflate/gzinflate
- gzcompress/gzuncompress
- fastlz_compress/fastlz_decompress https://github.com/t3rmin4t0r/php-fastlz/https://github.com/t3rmin4t0r/php-fastlz
- lzf_compress/lzf_decompress
压测代码
压测代码如下:
<?php
define('TEST_NUM', 50000);
function doCompress($func, $args) {
$start = microtime(true);
for($i = 0; $i < TEST_NUM; $i++) {
call_user_func_array($func, $args);
}
$cost = (microtime(true) - $start) * 1000;
printf("%s cost:%.3f\n", $func, $cost);
}
$funcMap = [
1 => 'gzencode',
2 => 'gzdecode',
3 => 'gzdeflate',
4 => 'gzinflate',
5 => 'gzcompress',
6 => 'gzuncompress',
7 => 'fastlz_compress',
8 => 'fastlz_decompress',
9 => 'lzf_compress',
10 => 'lzf_decompress',
];
$type = $argv[1] ?? 1;
//$str = str_repeat("你好sdfsdf", 1024);
$str = file_get_contents(__DIR__.'/file');
$args = [$str];
for($i = 2; $i < $argc; $i++) {
$args[] = $argv[$i];
}
if ($type % 2 ==0) {
$origLen = strlen($str);
printf("origin len:%d\n", $origLen);
$str = call_user_func_array($funcMap[$type - 1], $args);
$args[0] = $str;
$destLen = strlen($str);
printf("%s len:%d compRate:%.2f%%\n", $funcMap[$type -1], $destLen, ($destLen*100)/$origLen);
}
doCompress($funcMap[$type], $args);使用方法:
php TestCompress.php type [level]
- type 类型,对应代码中$funcMap的key。分别为1-10,对应不同的解压缩方法
- level 解压缩级别 此选项只有type=5或者6时有用。注意:
gzcompress有级别之分,从0-9共10个级别,数字越大,压缩得越厉害,处理时间也越长。
其他压缩方法没有级别之分。
压测结果
内容原始长度为3233个字节,每个算法各运算5w次。
压测结果如下:
| 压缩算法 | 解压时间(ms) | 解压算法 | 解压时间(ms) | 压缩比 |
|---|---|---|---|---|
| gzencode | 4147.639 | gzencode | 883.990 | 47.54% |
| gzdeflate | 3889.775 | gzinflate | 717.879 | 46.98% |
| gzcompress(2) | 2694.423 | gzuncompress(2) | 198.223 | 48.62% |
| gzcompress(6) | 3952.218 | gzuncompress(6) | 194.934 | 47.17% |
| gzcompress(9) | 4317.040 | gzuncompress(9) | 196.099 | 47.08% |
| fastlz_compress | 453.179 | fastlz_decompress | 182.741 | 58.65% |
| lzf_compress | 266.160 | lzf_decompress | 134.726 | 58.65% |
- 其中的gzcompress(9),使用第9级压缩,是之前在cache组件中采用的压缩方式,其缺点是显而易见的:压缩过程太耗时间了。
- fastlz的php扩展对php7的支持不好,在pecl没有官方的扩展,且需要修改源代码才能正常安装,难免有相应的隐患。
- lzf在pecl中有官方扩展,且php.net官网有专门的介绍。相比之下,其压缩率尚在可接受范围,且解压缩速度非常具有优势,可与采用。
结论
可以考虑使用lzf_compress/lzf_decompress来替换gz_compress/gz_uncompress。