压缩效率是压缩后体积÷原始体积,必须用os.Stat两次获取精确字节数,且需outputFile.Sync()确保落盘;gzip不同Level对文本压缩效率差异显著,BestSpeed仅减5–15%,BestCompression可压至20%以下,但CPU耗时增3–5倍。

直接看压缩比,别只盯着CPU时间——效率是压缩后体积 ÷ 原始体积,不是“快不快”
为什么os.Stat两次才能算准压缩效率
压缩效率本质是空间节省率,必须拿到原始文件和压缩后文件的精确字节数。很多人在gzip.Writer.Close()后立刻调用os.Stat(dst),但忽略了一个关键点:文件系统可能还没完成落盘(尤其在某些挂载选项或容器环境中),导致返回的Size偏小甚至为0。
- 务必在
gzipWriter.Close()之后、outputFile.Close()之前调用outputFile.Sync(),强制刷盘 - 再用
os.Stat(src)和os.Stat(dst)分别获取两个os.FileInfo - 计算公式固定为:
float64(compressedSize) / float64(originalSize),结果越小效率越高(如0.3表示压缩后只剩30%)
compress/gzip不同Level对效率的实际影响
压缩级别不是线性影响效率,而是明显分段:低级别(gzip.BestSpeed)几乎不压缩文本,高级别(gzip.BestCompression)对JSON/日志类数据提升显著,但对已压缩文件(如.jpg)反而可能变大。
-
gzip.NoCompression(0):无压缩,输出带gzip头,体积略增(+12–20字节) -
gzip.BestSpeed(1):仅做LZ77简单匹配,适合实时流,效率通常只比原始小5–15% -
gzip.DefaultCompression(-1):平衡点,多数场景下效率在30–50%,推荐作为基准测试起点 -
gzip.BestCompression(9):启用深度哈夫曼优化,对纯文本可压到20%以下,但CPU耗时可能翻3–5倍
实测时容易漏掉的三个干扰项
真实环境测效率,光跑一次compressFile()函数远远不够。下面这些因素会扭曲结果:
立即学习“go语言免费学习笔记(深入)”;
-
文件系统缓存:首次读取
src走的是page cache,第二次可能命中,建议每次测试前执行sync && echo 3 | sudo tee /proc/sys/vm/drop_caches(Linux) - 小文件误差:小于1KB的文件,gzip头部(18字节)占比过大,算出的“效率”失真,应排除或单独标注
-
缓冲区大小:用
io.CopyBuffer时若buffer太小(如1KB),I/O次数暴增,CPU时间被浪费在系统调用上,掩盖真实压缩开销;建议至少用128 * 1024(128KB)
真正要评估一个压缩方案是否高效,得在同一台机器、关闭swap、禁用CPU频率调节(sudo cpupower frequency-set -g performance)的前提下,反复测5次取中位数——因为单次测量里,磁盘寻道、GC抖动、后台进程都可能突然吃掉几毫秒。


















