为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用互斥体有效地读取和写入映射?

如何使用互斥体有效地读取和写入映射?

Go
猛跑小猪 2022-08-24 18:58:58
我正在阅读一个包含1kk +对象的json文件,我需要组织和计算一些数据,为此,我创建了两个映射,以便我可以写入和读取它,当我运行一个简单的循环时,代码需要40s才能完成,例如:var acc intfirstContent := make(map[string]int)secondContent := make(map[string]int)decoder := json.NewDecoder(bufio.NewReader(file))for decoder.More() {    var dt &MyStruct{}    decoder.Decode()    if _, ok := firstContent[dt.Name]; !ok {        firstContent["some-data"] = 1        acc++ // count the uniqueness    } else {        firstContent["some-data"] += 1    }    if _, ok := secondContent[dt.City]; !ok {        first["some-data"] = 1    } else {        first["some-data"] += 1    }}我试图优化使用并避免并发,但是当我使用它时,它需要更长的时间才能完成。goroutinesmutexvar mutex = sync.RWMutex{}for reader.More() {    var dt &MyStruct{}    reader.Decode(&dt)    go func(name string) {        mutex.Lock()        if _, ok := firstContent[name]; !ok {            firstContent[name] = 1 // need to convert to *int64, i know...            atomic.AddInt32(acc, 1)        } else {            atomic.AddInt64(firstContent[name], 1)        }        mutex.Unlock()    }(dt.Name)    go func(city string) {        mutex.Lock()        if _, ok := secondContent[city]; !ok {            secondContent[city] = 1        } else {            atomic.AddInt(secondContent[city], 1)        }        mutex.Unlock()    }(dt.City)}为什么需要更长的时间才能完成?以?在这种情况下,我该如何提高速度?mutex.Lock()
查看完整描述

2 回答

?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

就像上面的Jakub说的,你可以在单独的goroutines(如MapReduce框架)上拆分输入文件和进程,这肯定会加快速度。

另外,您是否尝试过在 JSON 文件中创建对象的 go-struct 并将其编组到它们的列表中,然后从那里进行计算?不知道那会不会更好,但这是一个想法。


查看完整回答
反对 回复 2022-08-24
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

您的问题无法通过并发来解决。花费大部分时间的是解析json,而不是计算名称。你可以说这种情况有点悖论,因为你必须在单个线程上读取文件。当然,如果可以的话,也许将文件拆分为较小的文件并在单独的线程上处理每个文件会有所帮助。


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信