压缩比本质是原始数据长度除以压缩后数据长度;需先完成压缩再取len(),gzip需调用Close()确保写入,且随机数据可能导致压缩后体积增大。

压缩比计算的本质是字节长度对比
压缩比不是 Go 标准库直接提供的函数,它只是个简单算术:原始数据长度除以压缩后数据长度。关键在于你得先完成压缩操作,再取两者的 len()。别被“压缩比”这个词唬住——它本身不涉及算法逻辑,只依赖你用的压缩方式是否真实降低了字节量。
用 gzip 压缩后算压缩比要注意内存和错误处理
Go 的 compress/gzip 是最常用选择,但容易漏掉两个细节:一是 gzip.Writer 必须调用 Close() 才能确保所有数据写入底层 buffer;二是如果原始数据本身含大量随机字节(比如已加密或已压缩过的数据),压缩后可能反而变大——这时压缩比会 ,属于正常现象,不是代码写错了。
示例片段:
func calcGzipRatio(data []byte) float64 {
var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
_, _ = gz.Write(data) // 忽略写入错误(data 总是可写)
gz.Close() // ⚠️ 必须调用,否则 buf 可能为空
return float64(len(data)) / float64(buf.Len())
}
zlib 和 zstd 的压缩比差异主要来自算法特性
标准库的 compress/zlib 默认压缩级别低、速度快,压缩比通常不如 gzip(同级别下);而第三方 github.com/klauspost/compress/zstd 支持更高压缩比和多线程,但需要额外 go get。选哪个不取决于“哪个更标准”,而取决于你的数据特征和性能要求:
立即学习“go语言免费学习笔记(深入)”;
- 日志文本、JSON、HTML 等重复结构多的数据:
zstd.WithEncoderLevel(zstd.SpeedBetterCompression)通常比默认gzip高 10%–25% - 小文件(zlib 启动开销更低,压缩比可能反超
- 实时流式场景:避免用高阶
zstd级别,CPU 占用会上升明显
别忽略原始数据是否已压缩这个前提
直接对 JPEG、MP4、ZIP 文件内容调用压缩函数,大概率得到 ratio 。这不是函数写错了,而是这些格式本身已是高压缩态。真正该测压缩比的,是原始日志、CSV、未压缩 JSON 或内存 dump 这类数据。如果业务中不确定输入来源,建议加一层快速检测:
比如检查前 4 字节是否匹配常见压缩魔数:0x1f8b(gzip)、0x789c(zlib)、0x28b52ffd(zstd)——匹配则跳过压缩,直接返回 1.0。
实际工程里,压缩比数字本身意义有限;更关键的是它在特定数据集上的稳定性。同一份样本反复跑,结果波动超过 ±5%,就得查 buffer 复用、编码转换(如 UTF-8 vs GBK)、或是否误把 string 当 []byte 传入了。


















