Основная проблема в том, что вы используете отдельный замок в каждой программе. Это не поможет сериализовать доступ к карте. Одна и та же блокировка должна использоваться в каждой процедуре.
И поскольку вы используете одну и ту же карту в каждой программе, вам не нужно объединять их, и вам не нужен канал для доставки результата.
Даже если вы используете один и тот же мьютекс в каждой программе, так как вы используете одну карту, это, вероятно, не повлияет на производительность, программы должны будут конкурировать друг с другом за блокировку карты.
Вы должны создать отдельную карту в каждой процедуре, использовать ее для локального подсчета, а затем доставить карту результатов на канал. Это может дать вам повышение производительности.
Но тогда вам не нужна блокировка, поскольку у каждой программы будет своя собственная карта, которую она может читать / записывать без мьютекса.
Но тогда вам нужно будет доставить результат по каналу, а затем объединить его.
И поскольку программы доставляют результаты по каналу, группа ожидания становится ненужной.
func WordCount(text string) map[string]int {
s := strings.Fields(text)
channel := make(chan map[string]int, 2)
go mappers(s[0:(len(s)/2)], channel)
go mappers(s[(len(s)/2):], channel)
total := map[string]int{}
for i := 0; i < 2; i++ {
m := <-channel
for k, v := range m {
total[k] += v
}
}
return total
}
func mappers(slice []string, ch chan map[string]int) {
occurrences := map[string]int{}
for _, word := range slice {
occurrences[word]++
}
ch <- occurrences
}
Пример тестирования этого :
fmt.Println(WordCount("aa ab cd cd de ef a x cd aa"))
Вывод (попробуйте на Go Playground ):
map[a:1 aa:2 ab:1 cd:3 de:1 ef:1 x:1]
Также обратите внимание, что в теории это выглядит "хорошо", но в На практике вы все еще не можете добиться какого-либо повышения производительности, поскольку программы выполняют слишком «небольшую» работу, а их запуск и объединение результатов требуют усилий, которые могут перевесить преимущества.