ディスクへの構造体の効率的な Go シリアル化: 肥大化を最小限に抑える
gob シリアル化によって生成される出力が肥大化しているにもかかわらず、より詳細な分析により、その後の同じタイプのエントリでは、12 バイトのオーバーヘッドのみが発生します。このオーバーヘッドは、長さ 4 バイトの 2 つの文字列 (長さのプレフィックスを含む) をエンコードするために必要な最小サイズを表します。
全体のファイル サイズを削減するには、次の戦略を検討してください:
コードデモ:
次の Go コードは、説明したさまざまなアプローチを示します:
package main import ( "bytes" "compress/bzip2" "compress/flate" "compress/gzip" "compress/zlib" "encoding/gob" "fmt" "io" ) type Entry struct { Key string Val string } func main() { // Create test data entries := make([]Entry, 1000) for i := 0; i < 1000; i++ { entries[i].Key = fmt.Sprintf("k%03d", i) entries[i].Val = fmt.Sprintf("v%03d", i) } // Test different encoding/compression techniques for _, name := range []string{"Naked", "flate", "zlib", "gzip", "bzip2"} { buf := &bytes.Buffer{} 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) } enc := gob.NewEncoder(out) for _, e := range entries { enc.Encode(e) } if c, ok := out.(io.Closer); ok { c.Close() } fmt.Printf("[%5s] Length: %5d, average: %5.2f / Entry\n", name, buf.Len(), float64(buf.Len())/1000) } }
出力:
[Naked] Length: 16053, average: 16.05 / Entry [flate] Length: 3988, average: 3.99 / Entry [ zlib] Length: 3994, average: 3.99 / Entry [ gzip] Length: 4006, average: 4.01 / Entry [bzip2] Length: 1977, average: 1.98 / Entry
から明らかなように出力では、圧縮技術を使用してファイル サイズが大幅に削減され、bzip2 では 1.98 という驚異的な圧縮率が達成されます。バイト/エントリ。
以上が最小限のファイル サイズで Go 構造体をディスクに効率的にシリアル化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。