go - 在保留顺序的同时对 slice 进行并发反序列化

标签 go concurrency

当前代码结构:

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。

目标:

  1. 并发反序列化并尽可能快地进行。
  2. 我需要保留原始 slice 的顺序
  3. 使用更易于阅读的 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/

相关文章:

java - java.lang.Class 方法线程安全吗?

.net - ConcurrentBag 中可能存在内存泄漏?

go - 将字符串 slice 的输出解析为另一个字符串 slice

go - GoLang 中使用 channel 的优先级队列

go - 使用 Go-Stomp 为 ActiveMQ 缓存连接

Linux Web 服务器并发文件处理(读/写)

java - 为什么我在这个不可修改集上收到 ConcurrentModificationException?

java - 为什么来自 'Concurrency in practice' 的 CooperatingNoDeadlock 使用与同一监视器的双同步?

go - 如何在 VS Code 中重新启用智能感知?

go - 如何将值附加到 ...interface{}?