Быстрая реализация буферов последовательностей, описанная в этой записи блога Гленном Фидлером на Go со 100%-ным покрытием модульных тестов.
Он был создан с целью создания надежных сетевых протоколов UDP, в которых буферы последовательностей могут использоваться в качестве эффективных, отказоустойчивых скользящих буферов фиксированного размера для:
Порядковые номера, используемые для буферизации записей, фиксированы и представляют собой 16-битные целые числа без знака, поскольку большее количество записей является избыточным и обеспечит незначительное улучшение вашей системы подтверждения пакетов.
Размер буфера должен делиться на максимальное значение 16-битного целого числа без знака (65536), иначе данные, буферизованные по порядковым номерам, не будут охватывать весь буфер. С этим столкнулись при написании тестов для этой библиотеки.
Метод RemoveRange
был протестирован и оптимизирован по сравнению с реализацией буфера последовательности в эталонной кодовой базе C Sustainable.io для использования нескольких вызовов memcpy
в циклах for.
Фактические последовательности и буферизованные данные хранятся в двух отдельных смежных фрагментах, так что записи, извлеченные из скользящего буфера, остаются в виде устаревшей памяти, которая при необходимости может быть позже подвергнута сборке мусора.
go get github.com/lithdew/seq
$ go test -bench=. -benchtime=10s
goos: linux
goarch: amd64
pkg: github.com/lithdew/seq
BenchmarkTestBufferInsert-8 327525945 35.6 ns/op 0 B/op 0 allocs/op
BenchmarkTestBufferRemoveRange-8 243091503 51.3 ns/op 0 B/op 0 allocs/op
BenchmarkTestBufferGenerateBitset32-8 84982886 137 ns/op 0 B/op 0 allocs/op