jellydator / ttlcache

An in-memory cache with item expiration and generics
MIT License
883 stars 115 forks source link

Optimize getOpts allocation in Get() method using sync.Pool #114

Closed tyr0chen closed 7 months ago

tyr0chen commented 8 months ago

Hi there,

I've noticed that in the Get() method, a new getOpts structure is created every time getWithOpts() is called. This frequent allocation of objects may lead to increased GC overhead. Have you considered using sync.Pool to optimize the allocation and reduce the GC pressure?

Using a sync.Pool to store and reuse getOpts instances can help minimize the number of allocations and deallocations, which in turn can improve the performance of the cache, especially in high-concurrency scenarios.

Here's a rough example of how sync.Pool could be used:

var getOptsPool = sync.Pool{
    New: func() interface{} {
        return &getOpts{}
    },
}

func (c *Cache) Get(key interface{}) (interface{}, bool) {
    opts := getOptsPool.Get().(*getOpts)
    value, ok := c.getWithOpts(key, opts)
    getOptsPool.Put(opts)
    return value, ok
}

Please let me know your thoughts on this suggestion. I'd be happy to contribute a PR if you think it's a worthwhile optimization.

Thank you!

swithek commented 8 months ago

Could you better explain how this might increase GC overhead? The getOpts value isn't a pointer nor is it being stored anywhere where GC might need to kick in.