ディスクへの構造体の効率的な Go シリアル化
問題:
最小化によるシリアル化パフォーマンスの最適化を使用して構造体をディスクにエンコードすると出力が肥大化するgob.
提案された解決策:
gob パッケージは効率的なシリアル化を提供しますが、エンコードに型情報が含まれるため、一意の型ごとに 26 バイトの初期オーバーヘッドが発生します。 。複数のインスタンスを持つ構造体の場合、このオーバーヘッドはそれら全体で償却できます。
代替:
このオーバーヘッドさえ許容できないアプリケーションの場合は、 flate などの圧縮技術の使用を検討してください。 zlib、gzip、または bzip2 を使用して、出力サイズをさらに削減します。 50-80%。
例:
次のコードは、gob を使用した単一エントリのオーバーヘッドを示しています。
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 }
複数のインスタンスの場合のエントリがシリアル化されている場合、オーバーヘッドはamortized:
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 中国語 Web サイトの他の関連記事を参照してください。