What is an object pool
Object pool is a design pattern that maintains a set of created objects. When using objects, they are directly retrieved from the object pool and put back into the object pool after use, rather than frequently creating and destroying objects. This can significantly reduce the pressure on the GC and improve the performance of the program.
Why not use it
is an object pool implementation provided by the Go standard library, but it has some limitations:
-
GC Uncertainty:
Objects in it may be recycled by GC, resulting in the need to be recreated every time the object is retrieved, losing the meaning of the object pool.
-
Limited applicable scenarios:
It is more suitable for the reuse of temporary objects, and the effect is not good for objects that need to exist for a long time.
- Insufficient control:There is no precise control of the size of the object pool and the life cycle of the object.
Therefore, in some scenarios, we need to customize the object pool for higher performance and control.
Hand-pushing object pool: Principle and implementation
Next, let’s take a simple object pool and analyze its principles.
1. Define the object pool structure
package main import ( "errors" "fmt" "sync" "time" ) type Pool struct { objects chan interface{} // Use channel to store objects factory func() interface{} // Create the factory function of the object mu // Protect the object pool} var g_index int = 0 func NewPool(size int, factory func() interface{}) *Pool { if size <= 0 { panic("Object pool size must be greater than 0") } pool := make(chan interface{}, size) for i := 0; i < size; i++ { pool <- factory() // Pre-create objects and put them in the object pool } return &Pool{ objects: pool, factory: factory, } } func (p *Pool) Get() interface{} { select { case obj := <-: return obj // Get object from object pool default: // The object pool is empty, create a new object ("create new object") () defer () return () } } func (p *Pool) Put(obj interface{}) error { select { case <- obj: // Put the object back to the object pool return nil default: // The object pool is full, discard the object obj2 := obj.(*MyObject) ("pool is full, discard object", ) obj = nil return ("pool is full") } } func (p *Pool) Len() int { return len() } type MyObject struct { Data string index int } func main() { // Create object factory objectFactory := func() interface{} { g_index += 1 return &MyObject{Data: "Initial Data", index: g_index} } // Create an object pool with a size of 10 pool := NewPool(10, objectFactory) var wg for i := 0; i < 100; i++ { (1) go func(idx int) { ("pool len:", ()) obj := ().(*MyObject) defer func() { () (obj) }() ("from :", , , idx) ( * 2) // Simulate some work }(i) } () }
Code explanation:
-
ObjectPool
The structure contains apool
channel, used to store objects. -
factory
is a function that creates new objects. -
NewObjectPool
Functions are used to create object pools and pre-create a specified number of objects into the object pool. -
Get
Functions are used to obtain objects from the object pool. If the object pool is empty, callfactory
Create a new object. -
Put
Functions are used to put objects back into the object pool. If the object pool is full, the object is discarded. - Define a
MyObject
Structure, as the object type stored in the object pool. - Create a
objectFactory
Functions for creatingMyObject
Object. - Create a pool of object size 10 and pass in
objectFactory
function. - Get the object from the object pool, modify the object's data, and then put the object back to the object pool.
- Get the object from the object pool again and you can see that the object's data has been modified, indicating that the object has been successfully reused.
Summarize
By hand-pushing the object pool, we can not only better understand the principle of the object pool, but also customize the object pool according to actual needs to obtain higher performance and control. In scenarios where objects are frequently created and destroyed, using object pools can significantly improve the performance of the program and say goodbye to GC nightmare!
This is the article about this article explaining the correct way to open object pools in Go language. For more related Go object pool content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!