Created
July 18, 2019 02:12
-
-
Save jaysoncena/ae2e3fbdc03e67b5b0dd5bd737eeaa24 to your computer and use it in GitHub Desktop.
`[]byte` pool using sync.Pool with different sizes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From https://github.com/golang/go/blob/7e394a2/src/net/http/h2_bundle.go#L998-L1043 | |
// Buffer chunks are allocated from a pool to reduce pressure on GC. | |
// The maximum wasted space per dataBuffer is 2x the largest size class, | |
// which happens when the dataBuffer has multiple chunks and there is | |
// one unread byte in both the first and last chunks. We use a few size | |
// classes to minimize overheads for servers that typically receive very | |
// small request bodies. | |
// | |
// TODO: Benchmark to determine if the pools are necessary. The GC may have | |
// improved enough that we can instead allocate chunks like this: | |
// make([]byte, max(16<<10, expectedBytesRemaining)) | |
var ( | |
http2dataChunkSizeClasses = []int{ | |
1 << 10, | |
2 << 10, | |
4 << 10, | |
8 << 10, | |
16 << 10, | |
} | |
http2dataChunkPools = [...]sync.Pool{ | |
{New: func() interface{} { return make([]byte, 1<<10) }}, | |
{New: func() interface{} { return make([]byte, 2<<10) }}, | |
{New: func() interface{} { return make([]byte, 4<<10) }}, | |
{New: func() interface{} { return make([]byte, 8<<10) }}, | |
{New: func() interface{} { return make([]byte, 16<<10) }}, | |
} | |
) | |
func http2getDataBufferChunk(size int64) []byte { | |
i := 0 | |
for ; i < len(http2dataChunkSizeClasses)-1; i++ { | |
if size <= int64(http2dataChunkSizeClasses[i]) { | |
break | |
} | |
} | |
return http2dataChunkPools[i].Get().([]byte) | |
} | |
func http2putDataBufferChunk(p []byte) { | |
for i, n := range http2dataChunkSizeClasses { | |
if len(p) == n { | |
http2dataChunkPools[i].Put(p) | |
return | |
} | |
} | |
panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment