当前代码结构:
func doStuff(serializeds []string) ([]*MyStruct, error) {
objs := []*MyStruct{}
for _, s := range serializeds {
deserializedObject, ok, err := doDeserialization(s)
if err != nil {
// if any err, abandon the whole thing
return nil, err
}
if !ok {
continue
}
objs = append(objs, deserializedObject)
}
return objs, nil
}
序列化数
通常一次包含 200-1000 个序列化字符串。对它们中的每一个进行反序列化
大约需要 0.5-1ms。
目标:
- 并发反序列化并尽可能快地进行。
- 我需要保留原始 slice 的顺序
- 使用更易于阅读的 channel 实现此功能
附带问题:为每个序列化字符串启动一个 goroutine 是否可以,或者只使用有限数量的 goroutine(例如 50 个 goroutine)是否更有效
最佳答案
您可以预先创建具有所需大小的输出 slice (您预先知道 serializeds
的长度),然后使用 Go 例程中的映射值及其原始索引填充此 slice slice :
wait := new(sync.WaitGroup)
objs := make([]YourStructType, len(serializeds))
for i, s := range serializeds {
wait.Add(1)
go func(j int) {
defer wait.Done()
deserializedObject, err := doDeserialization(s)
if err != nil {
// add error handling here
}
objs[j] = deserializedObject
}(j)
}
wait.Wait()
关于您的附带问题:这保证了对您的应用程序的两种实现进行全面分析。直觉上,我猜想 Go 的 goroutine 调度程序应该足够高效来处理这个问题而不会产生太多开销,并且您可能不应该为 goroutine worker pool 的额外复杂性而烦恼。但是,如果不进行分析,那充其量只是猜测。
关于go - 在保留顺序的同时对 slice 进行并发反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38229923/