Первый закон эталонных тестов: бессмысленные микробенчмарки дают бессмысленные результаты.
Ваши нереальные микробенчмарки не имеют смысла.
Синхронизация пакетов
import "sync"
тип Пул
Пул - это набор временных объектов, которые могут быть индивидуально сохранены и извлечены.
Любой элемент, сохраненный в пуле, может бытьудаляется автоматически в любое время без уведомления.Если в этом случае в пуле хранится единственная ссылка, элемент может быть освобожден.
Пул безопасен для одновременного использования несколькими программами.
Цель пула - кэшировать выделенные, но неиспользуемые элементы дляпозже используйте повторно, снимая давление на сборщик мусора.То есть он позволяет легко создавать эффективные, поточно-ориентированные бесплатные списки.Однако он подходит не для всех свободных списков.
Надлежащим использованием пула является управление группой временных элементов, которые совместно используются и могут использоваться повторно независимыми клиентами пакета, которые могут использоваться повторно.Пул позволяет амортизировать накладные расходы при распределении между многими клиентами.
Примером правильного использования пула является пакет fmt, который поддерживает динамическое хранилище временных выходных буферов.Хранилище масштабируется под нагрузкой (когда многие программы активно печатают) и сжимается при бездействии.
С другой стороны, свободный список, поддерживаемый как часть недолговечного объекта, не подходит для пула,поскольку накладные расходы плохо амортизируются в этом сценарии.Более эффективно, чтобы такие объекты реализовывали свой собственный свободный список.
Подходит ли sync.Pool
для вашего варианта использования?sync.Pool
подходит для вашего теста?Ваш сценарий использования и ваш тест совпадают?Является ли ваш вариант использования микробенчмарком?
При использовании пакета Go testing
для ваших искусственных тестов с отдельными тестами для make
стеков и выделений кучи, make
быстрее и медленнее, чем sync.Pool
.
Выход:
$ go test pool_test.go -bench=. -benchmem
BenchmarkMakeStack-4 2000000000 0.29 ns/op 0 B/op 0 allocs/op
BenchmarkMakeHeap-4 10000000 136 ns/op 1024 B/op 1 allocs/op
BenchmarkBytePool-4 100000000 17.2 ns/op 0 B/op 0 allocs/op
$
pool_test.go
:
package main
import (
"sync"
"testing"
)
func BenchmarkMakeStack(b *testing.B) {
for N := 0; N < b.N; N++ {
obj := make([]byte, 1024)
_ = obj
}
}
var obj []byte
func BenchmarkMakeHeap(b *testing.B) {
for N := 0; N < b.N; N++ {
obj = make([]byte, 1024)
_ = obj
}
}
var bytePool = sync.Pool{
New: func() interface{} {
b := make([]byte, 1024)
return &b
},
}
func BenchmarkBytePool(b *testing.B) {
for N := 0; N < b.N; N++ {
obj := bytePool.Get().(*[]byte)
_ = obj
bytePool.Put(obj)
}
}