结构到磁盘的高效 Go 序列化
问题:
通过最小化优化序列化性能使用以下命令将结构编码到磁盘时输出会膨胀gob.
建议的解决方案:
虽然 gob 包提供了高效的序列化,但它在编码中包含类型信息,导致每个唯一类型的初始开销为 26 个字节。对于具有多个实例的结构,此开销可以在它们之间分摊。
替代方案:
对于即使这种开销也是不可接受的应用程序,请考虑使用诸如 flate 之类的压缩技术, zlib、gzip 或 bzip2 以进一步减小输出大小50-80%。
示例:
以下代码演示了使用 gob 的单个 Entry 的开销:
package main import ( "bytes" "encoding/gob" "fmt" ) type Entry struct { Key string Val string } func main() { var buf bytes.Buffer enc := gob.NewEncoder(&buf) e := Entry{"k1", "v1"} enc.Encode(e) fmt.Println(buf.Len()) // Prints 48 bytes }
如果多个实例的 Entry 被序列化,开销被摊销:
for i := 0; i < 1000; i++ { e.Key = fmt.Sprintf("k%3d", i) e.Val = fmt.Sprintf("v%3d", i) enc.Encode(e) } fmt.Println(buf.Len()) // Prints 16036 bytes = 16.04 bytes/Entry
实现想要紧凑的序列化格式,可以使用额外的压缩技术:
import ( "compress/bzip2" "compress/flate" "compress/gzip" "compress/zlib" ) var out io.Writer switch name { case "Naked": out = buf case "flate": out, _ = flate.NewWriter(buf, flate.DefaultCompression) case "zlib": out, _ = zlib.NewWriterLevel(buf, zlib.DefaultCompression) case "gzip": out = gzip.NewWriter(buf) case "bzip2": out, _ = bzip2.NewWriter(buf, nil) }
使用压缩技术得到的输出大小:
Technique | Output Size | Average / Entry |
---|---|---|
Naked | 16036 bytes | 16.04 bytes |
flate | 4120 bytes | 4.12 bytes |
zlib | 4126 bytes | 4.13 bytes |
gzip | 4138 bytes | 4.14 bytes |
bzip2 | 2042 bytes | 2.04 bytes |
以上是如何高效地将 Go 结构体序列化到磁盘并最小化文件大小?的详细内容。更多信息请关注PHP中文网其他相关文章!