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

我正在阅读一个包含1kk +对象的json文件,我需要组织和计算一些数据,为此,我创建了两个映射,以便我可以写入和读取它,当我运行一个简单的循环时,代码需要40s才能完成,例如:


var acc int

firstContent := 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

    }

}

我试图优化使用并避免并发,但是当我使用它时,它需要更长的时间才能完成。goroutinesmutex


var 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()


猛跑小猪
浏览 84回答 2
2回答

幕布斯7119047

就像上面的Jakub说的,你可以在单独的goroutines(如MapReduce框架)上拆分输入文件和进程,这肯定会加快速度。另外,您是否尝试过在 JSON 文件中创建对象的 go-struct 并将其编组到它们的列表中,然后从那里进行计算?不知道那会不会更好,但这是一个想法。

肥皂起泡泡

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

相关分类

Go