上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
- 1. 初始化
- 2. 内存分配
- 3. 垃圾回收
- 4. 并发调度
- 5. 通道
- 6. 延迟调用
- 7. 终结器
- 8. 其他
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5.4.1 性能
预分配足够空间有助于提升性能,减少因扩张引发的内存分配和数据迁移操作。
package main import ( "testing" ) const max = 10000 //go:noinline func test(cap int) map[int]int { m := make(map[int]int, cap) for i := 0; i < max; i++ { m[i] = i } return m } // ------------------------------- func BenchmarkTest(b *testing.B) { for i := 0; i < b.N; i++ { test(0) } } func BenchmarkTestCap(b *testing.B) { for i := 0; i < b.N; i++ { test(max) } } /* $ go test -bench . -benchmem cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz BenchmarkTest-2 943 1091463 ns/op 687253 B/op 278 allocs/op BenchmarkTestCap-2 2242 567812 ns/op 322285 B/op 12 allocs/op */
字典内联存储有长度限制。如果超出,则重新分配内存并复制。
提示:1.18 上限是 128 字节。详情请阅读《下卷:8.4 字典》。
package main import ( "testing" ) const max = 100 //go:noinline func test[T any](v T) map[int]T { m := make(map[int]T, max) for i := 0; i < max; i++ { m[i] = v } return m } // ------------------------------- func Benchmark128(b *testing.B) { for i := 0; i < b.N; i++ { test([128]byte{1,2,3}) } } func Benchmark129(b *testing.B) { for i := 0; i < b.N; i++ { test([129]byte{1,2,3}) } } /* $ go test -bench . -benchmem Benchmark128-2 106706 11268 ns/op 21270 B/op 8 allocs/op Benchmark129-2 78174 13199 ns/op 17288 B/op 103 allocs/op */
扩张的内存不会因键值删除而收缩,必要时应新建字典。
package main import ( "runtime" "time" ) const max = 1000000 //go:noinline func test[T any](v T) map[int]T { m := make(map[int]T, max) for i := 0; i < max; i++ { m[i] = v } return m } func main() { m := test([128]byte{1,2,3}) // m := test([128 + 1]byte{1,2,3}) runtime.GC() clear(m) for i := 0; i < 5; i++ { time.Sleep(time.Second) runtime.GC() } runtime.KeepAlive(&m) } /* $ go build && GODEBUG=gctrace=1 ./test --- 128 ----------------- 内联:字典内存无法收缩,时间较短。 gc 2 @1.023s 0%: 293->293->293 MB, (forced) gc 3 @2.061s 0%: 293->293->293 MB, (forced) gc 4 @3.066s 0%: 293->293->293 MB, (forced) gc 5 @4.073s 0%: 293->293->293 MB, (forced) gc 6 @5.076s 0%: 293->293->293 MB, (forced) --- 128 + 1 ------------- 外联:外部对象被回收,时间较长。 gc 4 @0.335s 15%: 175->175->175 MB, (forced) gc 5 @1.420s 4%: 175->175->38 MB, (forced) gc 6 @2.452s 2%: 38->38->38 MB, (forced) gc 7 @3.474s 1%: 38->38->38 MB, (forced) gc 8 @4.497s 1%: 38->38->38 MB, (forced) */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论