Является ли запись в карту мьютекса с несколькими процедурами быстрее, чем одна? и почему? - PullRequest
0 голосов
/ 28 марта 2019

У меня есть SyncMap, заданный следующим образом:

type SyncMap struct {
    sync.Mutex
    Map map[int]string
}

И теперь я пишу в него двумя способами: с одной и той же программой и несколькими с помощью мьютекса.следующие коды:

smap := SyncMap{}
smap.Map = make(map[int]string)
t1 := time.Now()
for i := 0; i < 10000; i++ {
    smap.Map[i] = strconv.Itoa(i)
}
elapsed := time.Since(t1)
fmt.Println("t1 elapsed", elapsed)
s2map := SyncMap{}
s2map.Map = make(map[int]string)
t2 := time.Now()
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
    defer wg.Done()
    for i := 0; i < 5000; i++ {
        s2map.Lock()
        s2map.Map[i] = strconv.Itoa(i)
        s2map.Unlock()
    }
}()
go func() {
    defer wg.Done()
    for i := 5000; i < 10000; i++ {
        s2map.Lock()
        s2map.Map[i] = strconv.Itoa(i)
        s2map.Unlock()
    }
}()
wg.Wait()
elapsed2 := time.Since(t2)
fmt.Println("t2 elapsed", elapsed2)

Вывод следующим образом:

t1 elapsed 5.0363ms
t2 elapsed 5.9353ms

Попробуйте время сервировки, t1 всегда быстрее, чем t2.Итак, мой вопрос, как написано в заголовке.

Могу ли я понять, что это связано с использованием блокировки мьютекса?SyncMap в этом случае или пакет sync.Map в go просто предназначен для написания безопасных программ, а не для эффективности?И есть ли способ повысить эффективность при написании карты с несколькими программами?

Спасибо ~

1 Ответ

2 голосов
/ 28 марта 2019

Это довольно просто. Во втором сценарии с двумя программами из-за мьютекса может быть только одна программа, записывающая карту одновременно. Так что это на самом деле мало чем отличается от простого последовательного выполнения одной и той же программы. В любой момент времени только один горутин будет делать что угодно. Счетчики и циклы вообще не занимают много времени, поэтому их можно по существу игнорировать, большую часть времени занимает запись карты.

Однако у вас также есть дополнительные расходы на состязание за блокировку и за 10 000 операций блокировки и разблокировки, которые довольно дороги. Так что это означает, что в целом это будет медленнее.

Таким образом, использование большего количества подпрограмм не ускоряет процесс, если в данный момент выполняется только одна подпрограмма.

Для повышения эффективности используйте лучшую карту, например , или , . Созданная вами карта вообще не допускает параллелизма.

...