【发布时间】:2021-11-08 03:49:50
【问题描述】:
我一直在寻找最快/有效的方式来存储数据结构以持久保存在文件系统上。我遇到了gob module,它允许设置编码器和解码器,以便将结构转换为可以存储的 []byte(二进制)。
这相对容易 - 这是一个解码示例:
// Per item get request
// binary = []byte for the encoded binary from database
// target = struct receiving what's being decoded
func Get(path string, target *SomeType) {
binary = someFunctionToGetBinaryFromSomeDB(path)
dec := gob.NewDecoder(bytes.NewReader(binary))
dec.Decode(target)
}
但是,当我将其与 JSON 编码器/解码器进行基准测试时,我发现它的速度几乎是原来的两倍。当我创建一个循环来检索所有结构时,这一点尤其明显。经过进一步研究,我了解到每次创建一个新的解码器真的很昂贵。重新创建了大约 5000 个解码器。
// Imagine 5000 items in total
func GetAll(target *[]SomeType{}) {
results = getAllBinaryStructsFromSomeDB()
for results.next() {
binary = results.getBinary()
// Making a new decoder 5000 times
dec := gob.NewDecoder(bytes.NewReader(binary))
var target someType
dec.Decode(target)
// ... append target to []SomeType{}
}
}
我被困在这里试图弄清楚如何回收(减少重复使用回收!)用于列表检索的解码器。了解解码器需要一个 io.Reader,我认为可以“重置” io.Reader 并在同一地址使用同一阅读器进行 new 结构检索,同时仍在使用同一个解码器。我不知道该怎么做,我想知道是否有人有任何想法可以阐明。我正在寻找的是这样的:
// Imagine 5000 items in total
func GetAll(target *[]SomeType{}) {
// Set up some kind of recyclable reader
var binary []byte
reader := bytes.NewReader(binary)
// Make decoder based on that reader
dec := gob.NewDecoder(reader)
results = getAllBinaryStructsFromSomeDB()
for results.next() {
// Insert some kind of binary / decoder reset
// Then do something like:
reader.WriteTo(results.nextBinary())
var target someType
dec.Decode(target) // except of course this won't work
// ... append target to []SomeType{}
}
}
谢谢!
【问题讨论】:
-
您应该go.dev/blog/pprof 分析该代码 - 永远不要假设您知道您的周期在没有分析的情况下花费在哪里。始终用数据验证您的预感。
标签: go