Pond
Pond 是一个用于 Python 的高性能对象池库,它的内存占用更小、命中率更高。 更多细节可以参阅我们的用户指南或我的博客(https://qin.news)。
GitHub 地址:
https://github.com/t-baby/pondpond/
Pond 是一个 Python 中高效的通用对象池,具有性能好、内存占用小、命中率高的特点。基于近似统计的根据频率自动回收的能力,能够自动调整每个对象池的空闲对象数量。
因为目前 Python 目前没有比较好的、测试用例完备、代码注释完备、文档完善的对象池化库,同时目前的主流对象池库也没有比较智能的自动回收机制。Pond 可能是 Python 中第一个社区公开的测试用例完整,覆盖率 90% 以上、代码注释完备、文档完善的对象池化库。
Pond 灵感来自于 Apache Commons Pool、Netty Recycler、HikariCP、Caffeine,集合了多家的优点。其次 Pond 通过使用近似计数的方式以极小的内存空间统计每个对象池的使用频率,并且自动回收。
流量较为随机平均的情况下,默认策略和权重可以降低 48.85% 内存占用,借取命中率 100%。
流量较为符合 2/8 定律的情况下,默认策略和权重可以降低 45.7% 内存占用, 借取命中率 100%。
设计概述
Pond 主要由 FactoryDict、Counter、PooledObjectTree 三部分以及一个单独的回收线程构成。
FactoryDict
使用 Pond 需要实现对象工厂 PooledObjectFactory,PooledObjectFactory 提供对象的创建、初始化、销毁、验证等操作,由 Pond 调用。所以为了让对象池支持存放完全不同的对象,Pond 使用了一个字典来记录每个工厂类的名称和自己实现的工厂类的实例化对象。
每个 PooledObjectFactory 应该具备创建对象、销毁对象、验证对象是否还可用、重置对象四个功能。
比较特别的是 Pond 支持自动重置对象,因为某些场景下可能会存在对象中要先赋值进行传递,传递完又被回收的情况,为了避免污染建议这种场景下无比实现这个功能。
Counter
Counter 中保存了一个近似计数器。
PooledObjectTree
PooleedObjectTree 是个字典,每个 key 对应着一个先进先出的队列,这些队列都是线程安全的。每个队列中保存着多个 PooleedObject。PooledObejct 保存了创建时间、最后借出的时间以及实际需要的对象。
线程安全
Pond 的借用和回收都是线程安全的。Python 的 queue 模块提供了一个适用于多线程编程的先进先出(FIFO)数据结构。它可以用来安全地在生产者和消费者线程之间传递消息或其他数据。锁是调用者来处理的,所有多个线程能够安全且容易的使用同样的 Queue 实例工作。而 Pond 的借用和回收都是在操作 queue,所以基本可以认为是线程安全的。
借出机制
在使用 Pond 借出一个对象时,会先检查想要借出的对象的种类是否已经在 PooledObjectTree 存在,如果存在会检查这个对象的对象池是否为空&#