压缩率非固定值,需明确定义为原始大小/压缩后大小(或1−压缩后/原始表示压缩比例),其数值高度依赖数据类型与特征,单次测量无趋势意义,须控制算法、级别、数据类型等变量,批量处理同质样本方可有效对比。

压缩率不是固定值,得先定义清楚怎么算
压缩率通常指 原始大小 / 压缩后大小(有时也用 1 - 压缩后大小 / 原始大小 表示压缩比例),但这个值高度依赖输入数据特征:文本、日志、JSON、二进制可执行文件的压缩效果天差地别。直接对一个文件跑一次 gzip 得到的数字,无法反映“趋势”。要分析变化,必须控制变量——比如固定压缩算法、级别、输入数据类型,并批量处理多个样本。
- 别拿单个文件的两次压缩结果比“趋势”:哪怕同一文件,不同 Go 版本或
gzip.NewWriter默认行为微调都可能让结果浮动 0.5% - 真正可比的是同一批数据在不同参数下的表现,例如:对 100 个 1MB 日志片段,分别用
gzip.BestSpeed、gzip.DefaultCompression、gzip.BestCompression压缩,再统计中位数压缩率 - 注意
gzip对极小文件(
用 compress/gzip + os.Stat 实现批量压缩率采集
核心是写一个循环,对每个目标文件做三件事:读原始大小、压缩、读压缩后大小。关键点在于必须调用 gzip.Writer.Close(),否则 os.Stat 拿到的文件大小是未刷新的缓冲区状态,结果偏小且不可靠。
- 打开源文件用
os.Open,获取原始大小直接读fi.Size(),无需加载全文 - 压缩时用
gzip.NewWriterLevel(dstFile, level)显式指定级别,避免依赖默认值(Go 1.20+ 默认为DefaultCompression,但旧版本不同) - 压缩完立刻
dstFile.Close(),再调用os.Stat(dstPath)获取真实大小;别省略这步,defer dstFile.Close()在循环里会延迟到函数退出才生效 - 示例关键片段:
src, _ := os.Open(path) fi, _ := src.Stat() origSize := fi.Size() src.Close() <p>dst, _ := os.Create(path + ".gz") gw := gzip.NewWriterLevel(dst, gzip.BestCompression) io.Copy(gw, src) // 这里 src 已关闭?错——得重开 gw.Close() // 必须 dst.Close()</p><p>zipped, _ := os.Stat(path + ".gz") ratio := float64(origSize) / float64(zipped.Size())
解压失败或压缩率异常低?先检查数据可压缩性
如果批量计算发现某些文件压缩率接近 1.0(几乎不压缩),不要急着调参数——大概率是数据本身问题。加密数据、已压缩格式(如 JPG、MP4、ZIP)、随机字节流,gzip 几乎无法进一步压缩,强行提高级别只会拖慢速度,毫无收益。
- 快速判断:用
file命令看 MIME 类型,或用head -c 1024 path | hexdump -C观察是否有明显文本特征 - 对 JSON/YAML/CSV 等结构化文本,压缩率通常在 3–6x;对 protobuf 二进制,可能只有 1.1–1.3x
- 若一批文件中部分压缩率突降,优先怀疑是否混入了非目标类型(比如日志目录里误放了一个 .png)
- 别迷信
gzip.BestCompression:它比DefaultCompression多花 3–5 倍 CPU 时间,但压缩率提升常不足 5%,实测中位数差异往往
画趋势图前,先聚合再平滑
原始压缩率数据是离散点,直接连成折线容易被噪声干扰。尤其当文件大小跨度大(从 1KB 到 100MB),小文件的微小绝对误差会被放大成巨大相对误差。建议按文件大小分桶(如 [0, 1KB), [1KB, 10KB), …),每桶内取压缩率中位数而非平均值——中位数对异常值鲁棒得多。
立即学习“go语言免费学习笔记(深入)”;
- 用
sort.Slice按文件大小排序后分段,避免用map[float64][]float64手动分桶导致浮点精度问题 - 时间维度趋势(如每日归档日志的压缩率)需对齐采样周期:确保每天采集的都是同一类日志(如 access.log),而非混入 error.log 或 trace.log
- 若要用
gonum/plot绘图,x 轴建议用对数刻度(plot.LogScale),因为文件大小天然呈幂律分布 - 最易被忽略的一点:压缩率趋势本身不能直接指导优化。它只是信号——真正要查的是“为什么今天这批日志压缩率下降了 15%?”答案往往在上游:日志格式变更、新增了 base64 字段、采样率调整,而非压缩代码该改哪行


















