在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
原文:https://medium.com/swlh/go-the-idea-behind-sync-pool-32da5089df72 -----------------------
sync.Pool I was able to decrease the allocations and GC workload. sync package to create a self-managed temporary retrieval object pool. Why to use sync.Pool?sync.Pool can cache objects that are not used temporarily and use them directly (without reallocation) when they are needed next time. This can potentially reduce the GC workload and improve the performance. How to use sync.Pool?Put methods to retrieve and return objects. Also a Pool must not be copied after first use. interface{}. So you need to do a type assertion in order to get the concrete object // A dummy struct type Person struct { Name string } // Initializing pool var personPool = sync.Pool{ // New optionally specifies a function to generate // a value when Get would otherwise return nil. New: func() interface{} { return new(Person) }, } // Main function func main() { // Get hold of an instance newPerson := personPool.Get().(*Person) // Defer release function // After that the same instance is // reusable by another routine defer personPool.Put(newPerson) // Using the instance newPerson.Name = "Jack" } sync.Pool example Benchmarktype Person struct { Age int } var personPool = sync.Pool{ New: func() interface{} { return new(Person) }, } func BenchmarkWithoutPool(b *testing.B) { var p *Person b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < 10000; j++ { p = new(Person) p.Age = 23 } } } func BenchmarkWithPool(b *testing.B) { var p *Person b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < 10000; j++ { p = personPool.Get().(*Person) p.Age = 23 personPool.Put(p) } } }
Benchmark result: BenchmarkWithoutPool
Trade-offsync.Pool than simple initialization. func BenchmarkPool(b *testing.B) { var p sync.Pool b.RunParallel(func(pb *testing.PB) { for pb.Next() { p.Put(1) p.Get() } }) } func BenchmarkAllocation(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { i := 0 i = i } }) }
Benchmark result: BenchmarkPool
How does sync.Pool work?sync.Pool has two containers for objects: local pool (active) and victim cache (archived). registers to the runtime as a method to clean the pools. This method will be triggered by the GC. func init() {
When the GC is triggered, objects inside the victim cache will be collected and then objects inside the local pool will be moved to the victim cache. func poolCleanup() {
Get method will take an object from the victim cache in the first place and if the victim cache was empty the object will be taken from the local pool.
mutex lock and improves the shared access. Conclusionsync.Pool. mutex lock and improves the shared access. Conclusionsync.Pool.
|
请发表评论