高效的Go序列化结构到磁盘 [英] Efficient Go serialization of struct to disk

查看:329
本文介绍了高效的Go序列化结构到磁盘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是将C ++代码替换为Go,而我对Go API非常陌生。我正在使用gob将数百个键/值条目编码到磁盘页面,但gob编码有太多不需要的膨胀。

  package main 

import(
bytes
encoding / gob
fmt

type输入结构{
键字符串
Val字符串
}

func main( ){
var buf bytes.Buffer
enc:= gob.NewEncoder(& buf)
e:= Entry {k1,v1}
enc.Encode( e)
fmt.Println(buf.Bytes())
}

这会产生许多我不需要的膨胀:

  [35 255 129 3 1 1 5 69 110 116 114 121 1 255 130 0 1 2 1 3 75 101 121 1 12 0 1 3 86 97 108 1 12 0 0 0 11 255 130 1 2 107 49 1 2 118 49 0] 

我想序列化每个字符串的len,然后是原始字节,如:

  [0 0 0 2 107 49 0 0 0 2 118 49] 

我正在储蓄数百万条目,因此编码中的额外膨胀会使文件大小增加约10倍。



如何将它序列化为后者无需手动编码?

解决方案

使用protobuf可以高效地编码数据。

https://github.com/golang/protobuf



你的main看起来像这样:

  package main 

import(
fmt
log

github.com/golang/protobuf/proto


func main(){
e: =& Entry {
Key:proto.String(k1),
Val:proto.String(v1),
}
data,err:= proto .Marshal(e)
if err!= nil {
log.Fatal(marshaling error:,err)
}
fmt.Println(data)
}

您创建一个文件example.proto,如下所示:

  package main; 

消息条目{
required string Key = 1;
所需的字符串Val = 2;
}

您通过运行从原始文件生成转码:

  $ protoc --go_out =。 * .proto 

您可以检查生成的文件,如果您愿意的话。



您可以运行并查看结果输出:

  $ go run * .go 
[10 2 107 49 18 2 118 49]


I've been tasked to replace C++ code to Go and I'm quite new to the Go APIs. I am using gob for encoding hundreds of key/value entries to disk pages but the gob encoding has too much bloat that's not needed.

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.Bytes())
}

This produces a lot of bloat that I don't need:

[35 255 129 3 1 1 5 69 110 116 114 121 1 255 130 0 1 2 1 3 75 101 121 1 12 0 1 3 86 97 108 1 12 0 0 0 11 255 130 1 2 107 49 1 2 118 49 0] 

I want to serialize each string's len followed by the raw bytes like:

[0 0 0 2 107 49 0 0 0 2 118 49]

I am saving millions of entries so the additional bloat in the encoding increases the file size by roughly x10.

How can I serialize it to the latter without manual coding?

解决方案

Use protobuf to efficiently encode your data.

https://github.com/golang/protobuf

Your main would look like this:

package main

import (
    "fmt"
    "log"

    "github.com/golang/protobuf/proto"
)

func main() {
    e := &Entry{
        Key: proto.String("k1"),
        Val: proto.String("v1"),
    }
    data, err := proto.Marshal(e)
    if err != nil {
        log.Fatal("marshaling error: ", err)
    }
    fmt.Println(data)
}

You create a file, example.proto like this:

package main;

message Entry {
    required string Key = 1;
    required string Val = 2;
}

You generate the go code from the proto file by running:

$ protoc --go_out=. *.proto

You can examine the generated file, if you wish.

You can run and see the results output:

$ go run *.go
[10 2 107 49 18 2 118 49]

这篇关于高效的Go序列化结构到磁盘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆