Sync Pool is a tool to reuse memory allocations . and it can be shared among different threads.
- Based on the example, when we create a large struct, it will require more memory allocation
- Sync Pool can enable us to reuse the struct i.e. reuse the memory and reduce memory allocation
- Gin framework also uses Sync.pool to reduce memory allocation for Gin.Context as Context is large
- A new function needed in Sync.Pool for initialise and after Garbage Collection
- Those data could be lost anytime by Garbage Collection
- Not for communication between different thread
- not thread safe
- as it will be clear by Garbage Collection
- those data could be lost anytime by Garbage Collection
- Not for cacching
- not the same as redis
- reason as Garbage Collection above
- Why not a constant in the beginning then?
- mutate it instead of initialise a new
- it could be bad idea for 2 http requests to deserialise JSON data into the same struct
- as Sync.Pool is for reducing time of memory allocation
- common case will be initial struct (i.e. memory allocation) for JSON parse
- Remember put it back (Interesting)
- Otherwise, it will have a new memory allocation
- Sync.Pool.Put(c)
- Remember to reset the memory from Sync.Pool
- e.g. in JSON parsing, some JSON data may have no ID field, but previous JSON in sync.pool, previous JSON ID will show up in the new JSON parsing if there is no
- In gin.go in go library reset context after get from sync.pool
- Alternatives in Golang
- use [[Channel]] to self-made pool
- make a channel out of scopes of each requests to share
- in each request handler
- ask a channel to get the struct pointer
- if nothing, create a new struct pointer
- put into channel after finish request (i.e. defer in syntax)
- things to be concerned
- TBC: free memory if too many struct pointers in channel
- TBC: free memory if channel with some struct pointer is idle
- use [[Channel]] to self-made pool
- Summary
- Smaller type seems have bigger impact in the performance.
- in my machine: go version go1.15.5 darwin/amd64github.PullRequestEvent
- Pool without reset (INCORRECT)
- 237139 ns/op 81202 B/op 311 allocs/op
- Smaller type no pool without reset
- 181456 ns/op 65036 B/op 26 allocs/op
- However, most of the times, type size is already minimised
- Sync.pool will be a good option for reduce memory allocation.
- like what gin framework to reduce memory allocation for (context)[https://github.com/gin-gonic/gin/blob/master/gin.go#L188]
- results: https://github.com/wingleungchoi/justforfunc/blob/master/37-sync-pool/performances.txt
- Why not auto apply Sync.pool for big struct in Golang complier?
- Sync.pool also uses resources
- auto apply needs to implement optimised reset strategy
- not all the cases are similar to parsing data JSON in http request handler
- for example, a big struct in global scope of an APP will be referenced
- Auto applying Sync.pool is not helpful