- 机器学习
- 深度学习
- 数据可视化
- 可观测性
【免费下载链接】wandb
The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production.
Zstandard(简称 zstd)是一种实时压缩算法,在提供高压缩比的同时支持极宽的压缩/速度权衡区间,并拥有非常快的解码器。github.com/klauspost/compress/zstd是 Zstandard 的纯 Go 实现,它在本仓库中以 vendored 依赖的形式存在于 core/vendor/github.com/klauspost/compress/zstd,由 core/go.mod 声明的github.com/klauspost/compress v1.20.0间接引入,并被 Apache Arrow Go 实现的 IPC 层用作 zstd 编解码后端(见 compression.go)。读完本文,你将掌握该库的流式/块式压缩与解压 API、全部关键配置选项、并发与字典用法,以及它在 wandb 核心中的真实落点。
一、包定位:纯 Go、面向 64 位优化的 Zstandard 实现
该包提供 Zstandard 内容的压缩(Compressor)与解压(Decompressor)能力,核心特征包括:
- 纯 Go 实现:可通过构建标签
noasm和nounsafe禁用汇编优化与不安全代码特性; - 侧重速度:当前实现的高性能压缩算法聚焦于速度,同时兼顾压缩比;
- 64 位优化:包当前针对 64 位处理器做了大量优化,在 32 位处理器上会明显变慢;
- 稳定性承诺:压缩器与解压器均标记为 STABLE 状态,项目持续通过模糊测试(fuzz testing)验证,但项目方仍建议针对特定数据类型/尺寸/设置组合自行测试;
- 许可:以 Go 标准开源许可发布。
在 wandb 仓库中,该包并非被 wandb 自身 Go 源码直接 import,而是作为github.com/apache/arrow-go/v18的传递依赖被 vendored。core/vendor/modules.txt第 693–702 行记录了完整的 vendored 清单,包含github.com/klauspost/compress/zstd及其内部依赖zstd/internal/xxhash。真正使用它的是 Arrow IPC 压缩封装:其中zstdCompressor包装了*zstd.Encoder,zstdDecompressor包装了*zstd.Decoder,分别实现了 Arrow IPC 的Compressor/Decompressor接口,从而为 Arrow 数据流提供 zstd 压缩通道。因此,该库的 API 与性能直接关系到 wandb 核心中 Arrow 相关数据路径的编解码体验。
二、安装与引入
该库随github.com/klauspost/compress模块发布,包路径为github.com/klauspost/compress/zstd。对于使用本仓库的开发者,依赖已由 core/go.mod 锁定为v1.20.0并完成 vendoring,无需手动下载;在自己的 Go 工程中引入则执行:
go get -u github.com/klauspost/compress随后在代码中import "github.com/klauspost/compress/zstd"即可。由于 Go 模块语义,compress/zstd与本仓库核心中的其他 vendored 包遵循相同的版本锁定规则,升级时需同步更新go.mod与go.sum(仓库中对应条目见 go.sum)。
三、Compressor:压缩器使用指南
3.1 压缩级别与速度模型
目前实现了一个高速(fastest)和一个中高速(default)压缩器,压缩级别与官方 zstd 参考实现的对应关系如下:
| 本包级别 | 大致对应官方 zstd 级别 |
|---|---|
| Fastest(最快) | level 1 |
| Default(默认) | level 3(官方默认) |
| Better(更好) | level 7 |
| Best(最佳) | level 11 |
与 Go 标准库相比:其速度通常是标准库 deflate/gzip 最快模式的2 倍;压缩比约相当于 level 3,但速度通常是其3 倍。性能对比细节见文末“性能基准”一节。
3.2 流式压缩:NewWriter
Encoder 支持两种使用方式:通过io.WriteCloser接口进行流式压缩,或通过EncodeAll进行多个独立任务的块式压缩。较小数据量的编码建议使用EncodeAll。NewWriter创建的实例两种方式都可用。
默认选项创建 writer 的经典流式压缩示例:
// Compress input to output. func Compress(in io.Reader, out io.Writer) error { enc, err := zstd.NewWriter(out) if err != nil { return err } _, err = io.Copy(enc, in) if err != nil { enc.Close() return err } return enc.Close() }写入enc的数据即被编码,Close()调用时输出完整收尾。即使编码失败,也应当调用Close()释放可能持有的资源。
上述写法适合大体积编码;但只要可能就应复用 writer:通过Reset(io.Writer)切换到新的输出,让编码器复用全部内部资源,避免浪费分配。
关于并发,需要留意两点:
- 默认情况下,流式编码采用“轻量并发”,即最多 2 个 goroutine 参与流的一部分工作。这与
WithEncoderConcurrency(n)相互独立(未来可能变化),因此若希望限制未来版本的并发,应显式指定期望的并发数; - 若希望流式编码完全不启动异步 goroutine,使用
WithEncoderConcurrency(1),此时每个块完成即压缩,写操作会阻塞至该块完成。
3.3 并行流压缩:WithConcurrentBlocks
对于大流量吞吐有极致追求的场景,使用WithConcurrentBlocks(true)搭配WithEncoderConcurrency(n)(n 为想使用的 CPU 核心数)。该模式把输入切分为大段(jobs),由多个 goroutine 同时压缩,机制与 C 版 zstd 的多线程压缩类似:
enc, err := zstd.NewWriter(out, zstd.WithEncoderLevel(zstd.SpeedDefault), zstd.WithEncoderConcurrency(runtime.GOMAXPROCS(0)), zstd.WithConcurrentBlocks(true), )每个非首个 job 都会从前一个 job 获取重叠前缀作为匹配上下文,因此压缩比只受轻微影响;输出按顺序刷出,最终产生一个合法的单帧 zstd 流。项目文档给出的 1.8GB GOB 流基准(AMD Ryzen 9 9950X)如下:
| Level | 1 线程 | 4 线程 | 16 线程 | 1T 比率 | 16T 比率 |
|---|---|---|---|---|---|
| fastest | 783 MB/s | 2950 MB/s(3.8×) | 6939 MB/s(8.9×) | 12.24% | 12.26% |
| default | 728 MB/s | 2533 MB/s(3.5×) | 5340 MB/s(7.3×) | 10.67% | 10.68% |
| better | 434 MB/s | 1105 MB/s(2.5×) | 2206 MB/s(5.1×) | 9.14% | 9.21% |
| best | 129 MB/s | 367 MB/s(2.8×) | 884 MB/s(6.8×) | 8.48% | 8.63% |
(上表为项目 README 提供的基准数据,ratio 列指输出相对输入的比例,越低压缩比越高。)
使用该模式的注意事项:
- 与字典编码不兼容;
Flush()会立即派发当前部分完成的 job,对延迟敏感的场景可借此强制产出输出;EncodeAll不受影响——它经由编码器池走自己的并发路径。
压缩级别通过WithEncoderLevel()指定,目前仅支持预定义级别。
3.4 未来兼容性保证
该包处于持续演进中,压缩效率与速度都可能变化:
- 目标是维持默认效率在官方 zstd(level 3)水平;
- 不应假设编码输出恒定不变,不要用压缩输出的哈希做相似性比对;
- 同一代码版本可保证输出一致,未来可能出现破坏这一点的模式,但不会在未显式开启选项的情况下启用;
- 该编码器不设计为(未来也基本不会)与参考编码器输出完全一致的比特流。
另需注意(文档中对比 cgo 解压器时指出):cgo 解压器存在不报告部分输入错误、省略部分错误检查、忽略校验和、以及忽略拼接流(而拼接流是 zstd 规范的一部分)等问题——这也是纯 Go 实现的一个价值点。
3.5 块式压缩:EncodeAll
EncodeAll(src, dst []byte) []byte将src全部编码并追加到dst,可并发调用,每次调用只运行在调用者自己的 goroutine 上。编码后的块可以拼接,拼接结果即为合并输入流的合法输出;EncodeAll的产物既可用流式 Decoder 解码,也可用DecodeAll解码。
import "github.com/klauspost/compress/zstd" // Create a writer that caches compressors. // For this operation type we supply a nil Reader. var encoder, _ = zstd.NewWriter(nil) // Compress a buffer. // If you have a destination buffer, the allocation in the call can also be eliminated. func Compress(src []byte) []byte { return encoder.EncodeAll(src, make([]byte, 0, len(src))) }块编码尤其要注意复用 encoder:预热期后即可做到零分配;若再提供一个容量足够的 dst 缓冲区,可做到完全零分配。用WithEncoderConcurrency(n)可控制最大并发编码数。同一个 Encoder 同时用于流式与块式编码是安全的。
3.6 编码器选项速查(来自源码)
从 encoder_options.go 可以看到完整的 EOption 集合(函数行号以当前 vendored v1.20.0 为准):
| 选项 | 源码位置 | 说明 |
|---|---|---|
WithEncoderCRC(b bool) | encoder_options.go#L78 | 输出附加 CRC 值,输出增大 4 字节;可用ResetWithOptions更改 |
WithEncoderConcurrency(n int) | encoder_options.go#L89 | 设置编码并发数 |
WithWindowSize(n int) | encoder_options.go#L111 | 设置滑动窗口大小,影响内存与压缩比 |
WithEncoderPadding(n int) | encoder_options.go#L142 | 输出填充字节数 |
WithEncoderLevel(l EncoderLevel) | encoder_options.go#L236 | 压缩级别(四个预定义级别之一) |
WithZeroFrames(b bool) | encoder_options.go#L273 | 空输入时是否输出零帧 |
WithAllLitEntropyCompression(b bool) | encoder_options.go#L285 | 所有字面量熵编码压缩 |
WithNoEntropyCompression(b bool) | encoder_options.go#L297 | 禁用熵编码压缩 |
WithSingleSegment(b bool) | encoder_options.go#L315 | 单段(single segment)模式 |
WithLowerEncoderMem(b bool) | encoder_options.go#L327 | 降低编码器内存占用 |
WithConcurrentBlocks(b bool) | encoder_options.go#L345 | 开启多块并行压缩 |
WithEncoderDict(dict []byte) | encoder_options.go#L382 | 压缩时使用单个字典 |
WithEncoderDictRaw(id uint32, content []byte) | encoder_options.go#L398 | 以原始字典 ID 与内容注册字典 |
WithEncoderDictDelete() | encoder_options.go#L410 | 删除已注册字典 |
默认值在encoderOptions.setDefault()(encoder_options.go#L36-L48)中定义:并发数为runtime.GOMAXPROCS(0)、crc=true、块大小取最大压缩块、窗口大小8 << 20(8 MiB)、级别SpeedDefault。级别到具体编码器的映射见encoderOptions.encoder()(encoder_options.go#L51-L73):Fastest 对应fastEncoder、Default 对应doubleFastEncoder、Better 对应betterFastEncoder、Best 对应bestFastEncoder,且带字典时使用对应的*Dict变体。
四、Decompressor:解压器使用指南
状态:STABLE——仍可能存在细微 bug,但已测试大量内容,并持续接受模糊测试,主要目标是确保任何输入都无法导致解码器崩溃或越过其限制运行。
包的设计面向两类主要场景:大数据流与小体积内存缓冲,两者都通过创建Decoder来使用。
4.1 流式解压:NewReader
import "github.com/klauspost/compress/zstd" func Decompress(in io.Reader, out io.Writer) error { d, err := zstd.NewReader(in) if err != nil { return err } defer d.Close() // Copy content... _, err = io.Copy(out, d) return err }重要:默认设置下不再需要 Reader 时务必调用Close()以停止后台 goroutine。当返回错误(包括流结束的io.EOF)后,goroutine 会自行退出。
流按 4 个异步阶段并发解码以追求最佳吞吐;若希望同步解压,用WithDecoderConcurrency(1),数据只在被请求时才解压。
4.2 缓冲解压:DecodeAll
import "github.com/klauspost/compress/zstd" // Create a reader that caches decompressors. // For this operation type we supply a nil Reader. var decoder, _ = zstd.NewReader(nil, zstd.WithDecoderConcurrency(0)) // Decompress a buffer. We don't supply a destination buffer, // so it will be allocated by the decoder. func Decompress(src []byte) ([]byte, error) { return decoder.DecodeAll(src, nil) }解码器支持并发解压多个缓冲,默认创建 4 个解压器;可用WithDecoderConcurrency(n)调整允许的并发操作数,WithDecoderConcurrency(0)则创建 GOMAXPROCS 个解压器。
4.3 字典(Dictionaries)
使用字典压缩的数据可以被解压(字典是官方 zstd 针对小数据压缩的利器):
- 解码端:用
WithDecoderDicts(dicts ...[]byte)一次注册一个或多个字典。数据中指定了字典 ID 时会自动选用;复用的 Decoder 保留已注册字典;多个同 ID 字典注册时以最后一个为准; - 编码端:用
WithEncoderDict(dict []byte)启用单个字典,它会无条件使用(即使对压缩无益)。必须使用与压缩时相同的字典才能解压; - 要获得实际收益,字典应基于相似数据构建(官方
zstd --train命令生成);使用不合适的字典可能使输出比不用字典略大; - 目前用字典压缩存在固定的启动性能开销,实现前应测试性能影响。
4.4 零分配操作与资源管理
解码器设计目标之一是在预热后零分配运行,因此应长期持有(store)解码器:
- 流式解码器复用:
Reset(r io.Reader) error切换到另一条流;即使上一条流失败也可安全复用; - 释放资源:必须调用
Close(),之后该解码器不可再复用,但所有运行中的 goroutine 都会停止;不再需要 Reader 时务必调用; - 小缓冲解压可共用单个解码器;解码缓冲时,可传入长度为 0、容量为预期大小的目标切片,避免不必要分配。
4.5 解码器并发模型
- 缓冲解码器:全部工作在同一 goroutine 上完成,本身不并发;但可同时解码多个缓冲,用
WithDecoderConcurrency(n)限制; - 流式解码器:创建 goroutine 依次承担 4 个职责——(1)读取输入并切分为块;(2)字面量解压;(3)序列解压;(4)输出流重建。这也意味着解码器会“预读”并预生成数据,保证输出随时可用;
- 流的并发级别决定了解压会提前多少个块开始工作;由于块之间强依赖前一块的输出,流解码并发有限,实践中通常只能有效利用约3 个核心。
4.6 解码器选项速查(来自源码)
完整 DOption 集合见 decoder_options.go:
| 选项 | 源码位置 | 说明 |
|---|---|---|
WithDecoderLowmem(b bool) | decoder_options.go#L47 | 降低解码器内存占用 |
WithDecoderConcurrency(n int) | decoder_options.go#L68 | 并发解压数;0 表示 GOMAXPROCS |
WithDecoderMaxMemory(n uint64) | decoder_options.go#L90 | 解码内存上限 |
WithDecoderDicts(dicts ...[]byte) | decoder_options.go#L112 | 注册字典 |
WithDecoderDictRaw(id uint32, content []byte) | decoder_options.go#L131 | 注册原始字典 |
WithDecoderMaxWindow(size uint64) | decoder_options.go#L150 | 解码窗口上限 |
WithDecodeAllCapLimit(b bool) | decoder_options.go#L168 | 是否限制 DecodeAll 容量 |
WithDecodeBuffersBelow(size int) | decoder_options.go#L181 | 低于该尺寸的缓冲采用特定解码路径 |
WithDecoderDictDelete(ids ...uint32) | decoder_options.go#L203 | 按 ID 删除字典 |
五、性能基准
以下数据全部来自项目 README 的原始记录,反映该版本库在特定硬件与语料下的表现,不代表当前硬件环境的实测结果。
5.1 流式/缓冲解码基准(AMD Ryzen 9 3950X,AMD64 汇编)
BenchmarkDecoderSilesia-32 5 206878840 ns/op 1024.50 MB/s 49808 B/op 43 allocs/op BenchmarkDecoderEnwik9-32 1 1271809000 ns/op 786.28 MB/s 72048 B/op 52 allocs/op Concurrent blocks, performance(DecodeAll 并行解码): BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-32 67356 17857 ns/op 10321.96 MB/s 22.48 pct 102 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-32 266656 4421 ns/op 26823.21 MB/s 11.89 pct 19 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-32 20992 56842 ns/op 8477.17 MB/s 39.90 pct 754 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-32 27456 43932 ns/op 9714.01 MB/s 33.27 pct 524 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-32 78432 15047 ns/op 8319.15 MB/s 40.34 pct 66 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-32 65800 18436 ns/op 8249.63 MB/s 37.75 pct 88 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-32 102993 11523 ns/op 35546.09 MB/s 3.637 pct 143 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-32 1000000 1070 ns/op 95720.98 MB/s 80.53 pct 3 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-32 749802 1752 ns/op 70272.35 MB/s 100.0 pct 5 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-32 22640 52934 ns/op 13263.37 MB/s 26.25 pct 1014 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/html.zst-32 226412 5232 ns/op 19572.27 MB/s 14.49 pct 20 B/op 0 allocs/op BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-32 923041 1276 ns/op 3194.71 MB/s 31.26 pct 0 B/op 0 allocs/op(“pct”为压缩后大小占原大小的百分比;该项目记录于约 2022 年 5 月,可能已过时。)
5.2 压缩器跨实现对比
README 使用多种语料对比本包(表中zskp)与 Datadog cgo 库(zstd)、标准库 gzip 与本包 gzip 实现(gzstd/gzkp)。level取值中,本包 1=fastest、2=default、3=better、4=best。节选如下:
Silesia 语料(约 202 MB tar):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 211947520 | 73821326 | 634 | 318.47 |
| zskp | 2 | 211947520 | 67655404 | 1508 | 133.96 |
| zskp | 3 | 211947520 | 64746933 | 3000 | 67.37 |
| zskp | 4 | 211947520 | 60073508 | 16926 | 11.94 |
| zstd(cgo) | 1 | 211947520 | 73605392 | 543 | 371.56 |
| zstd(cgo) | 3 | 211947520 | 66793289 | 864 | 233.68 |
| zstd(cgo) | 6 | 211947520 | 62916450 | 1913 | 105.66 |
| zstd(cgo) | 9 | 211947520 | 60212393 | 5063 | 39.92 |
| gzstd | 1 | 211947520 | 80007735 | 1498 | 134.87 |
| gzkp | 1 | 211947520 | 80088272 | 1009 | 200.31 |
高度可压缩的 GOB 二进制流(约 1.9 GB):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 1911399616 | 233948096 | 3230 | 564.34 |
| zskp | 2 | 1911399616 | 203997694 | 4997 | 364.73 |
| zskp | 3 | 1911399616 | 173526523 | 13435 | 135.68 |
| zskp | 4 | 1911399616 | 162195235 | 47559 | 38.33 |
| zstd(cgo) | 1 | 1911399616 | 249810424 | 2637 | 691.26 |
| zstd(cgo) | 3 | 1911399616 | 208192146 | 3490 | 522.31 |
| zstd(cgo) | 6 | 1911399616 | 193632038 | 6687 | 272.56 |
| zstd(cgo) | 9 | 1911399616 | 177620386 | 16175 | 112.70 |
| gzstd | 1 | 1911399616 | 357382013 | 9046 | 201.49 |
| gzkp | 1 | 1911399616 | 359136669 | 4885 | 373.08 |
enwik9(2006-03-03 英文维基百科前 10^9 字节):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 1000000000 | 343833605 | 3687 | 258.64 |
| zskp | 2 | 1000000000 | 317001237 | 7672 | 124.29 |
| zskp | 3 | 1000000000 | 291915823 | 15923 | 59.89 |
| zskp | 4 | 1000000000 | 261710291 | 77697 | 12.27 |
| zstd(cgo) | 1 | 1000000000 | 358072021 | 3110 | 306.65 |
| zstd(cgo) | 3 | 1000000000 | 313734672 | 4784 | 199.35 |
| zstd(cgo) | 6 | 1000000000 | 295138875 | 10290 | 92.68 |
| zstd(cgo) | 9 | 1000000000 | 278348700 | 28549 | 33.40 |
| gzstd | 1 | 1000000000 | 382578136 | 8608 | 110.78 |
| gzkp | 1 | 1000000000 | 382781160 | 5628 | 169.45 |
高度可压缩 JSON(约 6.27 GB):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 6273951764 | 697439532 | 9789 | 611.17 |
| zskp | 2 | 6273951764 | 610876538 | 18553 | 322.49 |
| zskp | 3 | 6273951764 | 517662858 | 44186 | 135.41 |
| zskp | 4 | 6273951764 | 464617114 | 165373 | 36.18 |
| zstd(cgo) | 1 | 6273951764 | 766284037 | 8450 | 708.00 |
| zstd(cgo) | 3 | 6273951764 | 661889476 | 10927 | 547.57 |
| zstd(cgo) | 6 | 6273951764 | 642756859 | 22996 | 260.18 |
| zstd(cgo) | 9 | 6273951764 | 601974523 | 52413 | 114.16 |
| gzstd | 1 | 6273951764 | 1164397768 | 26793 | 223.32 |
| gzkp | 1 | 6273951764 | 1120631856 | 17693 | 338.16 |
VM 镜像 tar(约 8.56 GB):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 8558382592 | 3718400221 | 18206 | 448.29 |
| zskp | 2 | 8558382592 | 3326118337 | 37074 | 220.15 |
| zskp | 3 | 8558382592 | 3163842361 | 87306 | 93.49 |
| zskp | 4 | 8558382592 | 2970480650 | 783862 | 10.41 |
| zstd(cgo) | 1 | 8558382592 | 3609250104 | 17136 | 476.27 |
| zstd(cgo) | 3 | 8558382592 | 3341679997 | 29262 | 278.92 |
| zstd(cgo) | 6 | 8558382592 | 3235846406 | 77904 | 104.77 |
| zstd(cgo) | 9 | 8558382592 | 3160778861 | 140946 | 57.91 |
| gzstd | 1 | 8558382592 | 3926234992 | 51345 | 158.96 |
| gzkp | 1 | 8558382592 | 3960117298 | 36722 | 222.26 |
CSV 数据(约 3.33 GB):
| 输出 | level | insize | outsize | millis | mb/s |
|---|---|---|---|---|---|
| zskp | 1 | 3325605752 | 641319332 | 9462 | 335.17 |
| zskp | 2 | 3325605752 | 588976126 | 17570 | 180.50 |
| zskp | 3 | 3325605752 | 529329260 | 32432 | 97.79 |
| zskp | 4 | 3325605752 | 474949772 | 138025 | 22.98 |
| zstd(cgo) | 1 | 3325605752 | 687399637 | 8233 | 385.18 |
| zstd(cgo) | 3 | 3325605752 | 598514411 | 10065 | 315.07 |
| zstd(cgo) | 6 | 3325605752 | 570522953 | 20038 | 158.27 |
| zstd(cgo) | 9 | 3325605752 | 517554797 | 64565 | 49.12 |
| gzstd | 1 | 3325605752 | 928654908 | 21270 | 149.11 |
| gzkp | 1 | 3325605752 | 922273214 | 13929 | 227.68 |
综合可见:本包在 1/2 级(fastest/default)下压缩比与 cgo 实现接近,速度处于同一数量级,且远超 gzip;级别越高,压缩比收益越明显,但耗时增长也越陡峭。选型时应在吞吐与压缩比之间按数据特征取舍。
六、ZIP 归档内的 zstd
可以在 zip 归档内用 zstandard 压缩单个文件(虽然支持面不广,但对内部文件很有用)。为此必须注册压缩器与解压器,代码示例可参考包文档中的ZipCompressor示例(实现位于 zip.go)。
两条关键建议:
- 强烈建议在单个 zip Reader/Writer 实例上注册,而不是使用全局注册函数——来自不同包的两处全局注册会触发 panic;
- 最好只维护单一压缩器与解压器实例:它们可被多个 zip 文件并发使用,且单实例有助于复用部分资源。
七、在 wandb 仓库中的实际应用
在 wandb 核心(core 目录)中,klauspost/compress/zstd通过 Apache Arrow Go 库(github.com/apache/arrow-go/v18)被间接引入,具体落点在 Arrow IPC 压缩封装:
- 第 25 行
import "github.com/klauspost/compress/zstd"; zstdCompressor(第 48 行起)内嵌*zstd.Encoder,通过zstd.NewWriter(nil)构造,并实现MaxCompressedLen、Type等接口方法(第 52–78 行);zstdDecompressor(第 89 行起)内嵌*zstd.Decoder,通过zstd.NewReader(nil)构造,实现Reset、Close等接口方法(第 93–120 行)。
这意味着凡是启用 zstd 压缩的 Arrow IPC 数据通道,编解码底层都由本包承担;而 wandb 自身 Go 业务代码(core/internal等)并不直接引用它,依赖关系在 core/go.mod 中标记为// indirect。对 wandb 的开发者而言,理解本文所述的并发模型、窗口/内存选项与字典行为,有助于在涉及 Arrow 数据压缩时做出正确的性能与内存取舍。
八、参与贡献
项目欢迎一切贡献:新特性/修复请附带测试,性能增强请附带基准(benchmark)数据;一般反馈与使用经验可提交 issue。该包还内嵌了优秀的 xxhash 实现(版权归 Caleb Spare / cespare,2016),位于 zstd/internal/xxhash。
核心参考路径:
- 包文档:README.md
- 编码器入口与选项:encoder.go、encoder_options.go
- 解码器入口与选项:decoder.go、decoder_options.go
- 字典支持:dict.go
- ZIP 集成:zip.go
- 依赖声明:core/go.mod、core/vendor/modules.txt
- wandb 内实际使用:Arrow IPC 压缩封装
- 机器学习
- 深度学习
- 数据可视化
- 可观测性
【免费下载链接】wandb
The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production.
相关推荐
skopeo 依赖库剖析:klauspost/compress/zstd 纯 Go 版 Zstandard 压缩/解压实战指南
skopeo 依赖库剖析:klauspost/compress/zstd 纯 Go 版 Zstandard 压缩/解压实战指南 本文以仓库 vendor 目录中
云原生CLI镜像仓库OpenCloud 依赖解析:纯 Go 实现的 Zstandard 压缩库 klauspost/compress/zstd 完整指南
OpenCloud 依赖解析:纯 Go 实现的 Zstandard 压缩库 klauspost/compress/zstd 完整指南 本文以 OpenCloud
后端微服务存储认证鉴权Slim(toolkit) 依赖解析:深入 klauspost/compress/zstd 纯 Go 实现的 Zstandard 压缩/解压指南
Slim toolkit 依赖解析:深入 klauspost/compress/zstd 纯 Go 实现的 Zstandard 压缩/解压指南 导读 本文以当前
云原生CLI应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考