Укажите емкость контейнера, где это возможно, чтобы заранее выделить память для контейнера. Это минимизирует последующие выделения (путем копирования и изменения размера контейнера) по мере добавления элементов.
Указание подсказок емкости карты
По возможности предоставляйте подсказки (hint) по емкости при инициализации карт с помощью make().
make(map[T1]T2, hint)
Предоставление подсказки о емкости для make() приводит к попытке подобрать правильный размер карты во время инициализации, что снижает потребность в увеличении карты и распределении по мере добавления элементов в карту.
Обратите внимание, что, в отличие от срезов, подсказки емкости карты не гарантируют полного упреждающего выделения, но используются для приблизительного определения количества требуемых сегментов хэш-карты. Следовательно, выделения могут все еще происходить при добавлении элементов в карту, даже до указанной емкости.
Менее удачный вариант:
m := make(map[string]os.FileInfo)
files, _ := ioutil.ReadDir("./files")
for _, f := range files {
m[f.Name()] = f
}
m создается без указания размера; во время назначения может быть больше выделений.
Более удачный вариант:
files, _ := ioutil.ReadDir("./files")
m := make(map[string]os.FileInfo, len(files))
for _, f := range files {
m[f.Name()] = f
}
m создается с подсказкой размера; во время назначения может быть меньше выделений.
Указание емкости среза
По возможности предоставляйте подсказки о емкости при инициализации срезов с помощью make(), особенно при планировании дальнейших добавлений в срез.
make([]T, length, capacity)
В отличие от карт, емкость среза не является подсказкой: компилятор выделит достаточно памяти для емкости среза, как это предусмотрено для make(), что означает, что последующие операции append() будут нести нулевые выделения (до тех пор, пока длина среза не будет соответствовать емкости (capacity), указанной при создании среза, после чего любые добавления потребуют изменения размера для хранения дополнительных элементов).
Менее удачный вариант:
for n := 0; n < b.N; n++ {
data := make([]int, 0)
for k := 0; k < size; k++{
data = append(data, k)
}
}
BenchmarkBad 100000000 2.48s
Более удачный вариант:
for n := 0; n < b.N; n++ {
data := make([]int, 0, size)
for k := 0; k < size; k++{
data = append(data, k)
}
}
BenchmarkGood 100000000 0.21s
Читайте также:
- Go style guides: производительность, strconv вместо fmt, преобразования строки в байты
- Go style guides: избегайте встраивания типов в общедоступные структуры
- Go style guides: избегайте использования init()
Комментариев нет:
Отправить комментарий