Является ли запись в карту мьютекса с несколькими процедурами быстрее, чем одна? и почему?
У меня есть SyncMap, определенный следующим образом:
type SyncMap struct {
sync.Mutex
Map map[int]string
}
И теперь я пишу в него двумя способами: одним goroutine и несколькими goroutines с мьютексом. коды, как следует:
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 ответ
Это довольно просто. Во втором сценарии с двумя программами из-за мьютекса может быть только одна программа, записывающая карту одновременно. Так что это на самом деле мало чем отличается от простого последовательного выполнения одной и той же программы. В любой момент времени только один горутин будет делать что угодно. Счетчики и циклы вообще не занимают много времени, поэтому их можно по существу игнорировать, большую часть времени занимают записи на карту.
Однако у вас также есть дополнительные расходы на состязание за блокировку и 10000 операций блокировки и разблокировки, которые довольно дороги. Так что это означает, что в целом это будет медленнее.
Таким образом, использование большего количества подпрограмм не ускоряет процесс, если в данный момент выполняется только одна подпрограмма.
Для большей эффективности используйте лучшую карту, такую или эту. Карта, которую вы создали, не допускает параллелизма вообще.