fmt.Printf可一次性打印多个值,只需在格式字符串中按顺序使用占位符(如%t、%d、%s),再依次传入对应变量,例如fmt.Printf("%t\n%t\n", f1, f2);需确保占位符数量与参数数量一致且类型匹配,否则会panic。

怎么用 fmt.Printf 打印压缩比数值
压缩比不是内置函数返回的值,得自己算:用原始字节数除以压缩后字节数。注意别反了——fmt.Printf("ratio: %.2f", float64(len(original))/float64(len(compressed))) 才是「原始大小 / 压缩后大小」,结果大于 1 表示有压缩效果。
常见错误是直接用 len(original) / len(compressed) 做整数除法,结果恒为 0 或 1;必须转成 float64 再算。
为什么 gz.Close() 漏掉会导致压缩比恒为 1
没调 gz.Close() 时,buf.Bytes() 可能为空、或只含未压缩的原始数据(取决于 buffer 状态),导致 len(compressed) 等于甚至大于原始长度,算出来压缩比 ≤ 1,误判“没压缩”。
-
gz.Flush()不够:它只刷压缩块,不写 gzip trailer(CRC32 + ISIZE),解压会失败,且buf.Bytes()也不完整 -
defer gz.Close()在函数开头写很危险:如果中间Write()出错提前 return,Close()还没执行,压缩流就丢了 - 正确姿势:写完
Write()后立刻gz.Close(),并检查返回的 error
怎么在压缩时同时拿到原始大小、压缩大小和耗时
测量必须在同一次执行中完成,否则缓存、GC、调度干扰结果。关键点是:计时起点在 Write() 前,终点在 Close() 后;大小读取必须在 Close() 成功之后。
立即学习“go语言免费学习笔记(深入)”;
- 原始大小直接
len([]byte(input)) - 压缩后大小必须等
gz.Close()返回 nil 后再取buf.Len()(buf.Bytes()长度也行,但buf.Len()更轻量) - 不要用
time.Sleep或空循环凑时间——Go 的time.Now()足够精确
示例片段:
start := time.Now()
_, err := gz.Write(data)
if err != nil { /* handle */ }
err = gz.Close()
if err != nil { /* handle */ }
elapsed := time.Since(start)
originalSize := len(data)
compressedSize := buf.Len()压缩比接近 1.0 但实际没压缩,可能是数据本身问题
不是所有数据都适合 gzip。以下情况压缩比天然难低于 1.2:
- 输入太短(比如
- 内容已强压缩过(如
.jpg、.png、.mp4字节切片) - 随机字节(如加密后的 token)几乎没有重复模式,deflate 算法无从下手
- 用了
gzip.NoCompression级别(即 0)——这等于只打包不压缩
真正该测压缩比的,是纯文本、JSON、日志行这类高冗余数据。如果拿一段 base64 编码的图片去压,看到 ratio=1.03 别慌,这是正常的。



















