snapshot of https://github.com/uber-go/guide.git (master, 2026-09-15; blobs > 131072B omitted)

This commit is contained in:
upstream-mirror
2026-09-15 21:54:05 +05:00
commit a9c6c3ea36
73 changed files with 8782 additions and 0 deletions

119
src/container-capacity.md Normal file
View File

@@ -0,0 +1,119 @@
# Prefer Specifying Container Capacity
Specify container capacity where possible in order to allocate memory for the
container up front. This minimizes subsequent allocations (by copying and
resizing of the container) as elements are added.
## Specifying Map Capacity Hints
Where possible, provide capacity hints when initializing
maps with `make()`.
```go
make(map[T1]T2, hint)
```
Providing a capacity hint to `make()` tries to right-size the
map at initialization time, which reduces the need for growing
the map and allocations as elements are added to the map.
Note that, unlike slices, map capacity hints do not guarantee complete,
preemptive allocation, but are used to approximate the number of hashmap buckets
required. Consequently, allocations may still occur when adding elements to the
map, even up to the specified capacity.
<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>
```go
files, _ := os.ReadDir("./files")
m := make(map[string]os.DirEntry)
for _, f := range files {
m[f.Name()] = f
}
```
</td><td>
```go
files, _ := os.ReadDir("./files")
m := make(map[string]os.DirEntry, len(files))
for _, f := range files {
m[f.Name()] = f
}
```
</td></tr>
<tr><td>
`m` is created without a size hint; the map will resize
dynamically, causing multiple allocations as it grows.
</td><td>
`m` is created with a size hint; there may be fewer
allocations at assignment time.
</td></tr>
</tbody></table>
## Specifying Slice Capacity
Where possible, provide capacity hints when initializing slices with `make()`,
particularly when appending.
```go
make([]T, length, capacity)
```
Unlike maps, slice capacity is not a hint: the compiler will allocate enough
memory for the capacity of the slice as provided to `make()`, which means that
subsequent `append()` operations will incur zero allocations (until the length
of the slice matches the capacity, after which any appends will require a resize
to hold additional elements).
<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>
```go
for n := 0; n < b.N; n++ {
data := make([]int, 0)
for k := 0; k < size; k++{
data = append(data, k)
}
}
```
</td><td>
```go
for n := 0; n < b.N; n++ {
data := make([]int, 0, size)
for k := 0; k < size; k++{
data = append(data, k)
}
}
```
</td></tr>
<tr><td>
```plain
BenchmarkBad-4 100000000 2.48s
```
</td><td>
```plain
BenchmarkGood-4 100000000 0.21s
```
</td></tr>
</tbody></table>