当前位置:首页 > IT科技

手撸一个对象池,你学会了吗?

 什么是手撸对象池?

对象的池子,与线程池、个对内存池类似,象池学减少频繁创建和销毁对象带来的手撸成本(特别是消耗资源较大的云服务器对象),可用于实现对象的个对缓存和复用。这也算是象池学一种设计模式。

话不多说,手撸直接上代码:

#include <algorithm> #include <cassert> #include <cmath> #include <complex> #include <iostream> #include <memory> #include <numeric> #include <vector> struct A {      A(std::string s) {  str_ = std::move(s); }     void print() {  std::cout << str_ << std::endl; }     std::string str_; }; template <typename T,个对 typename Allocator = std::allocator<T>> class ObjectPool {     public:     ObjectPool() = default;     ~ObjectPool() {          assert(freeObjects_.size() == kInitChunkSize * (std::pow(2, pool_.size()) - 1));         size_t chunkSize{ kInitChunkSize};         for (auto* chunk : pool_) {              allocator_.deallocate(chunk, chunkSize);             chunkSize *= 2;         }         pool_.clear();     }     template <typename... Args>     std::shared_ptr<T> acquireObject(Args... args) {          if (freeObjects_.empty()) {              addChunk();         }         T* object{ freeObjects_.back()};         new (object) T{ std::forward<Args>(args)...};         freeObjects_.pop_back();         return std::shared_ptr<T>(object, [this](T* object) {              std::_Destroy(object);             freeObjects_.push_back(object);         });     }    private:     std::vector<T*> pool_;     std::vector<T*> freeObjects_;     static const size_t kInitChunkSize{ 5};     size_t newChunkSize{ kInitChunkSize};     void addChunk() {          std::cout << "add Chunk \n";         auto* firstNewObject{ allocator_.allocate(newChunkSize)};         pool_.push_back(firstNewObject);         auto oldFreeObjectSize{ freeObjects_.size()};         freeObjects_.resize(oldFreeObjectSize + newChunkSize);         std::iota(std::begin(freeObjects_) + oldFreeObjectSize, std::end(freeObjects_), firstNewObject);         newChunkSize *= 2;     }     Allocator allocator_; }; using APool = ObjectPool<A>; int main() {      APool pool;     for (int i = 0; i < 20; i++) {          auto x = pool.acquireObject(std::string("hello"));         x->print();     }     return 0; } 

上面的高防服务器对象池实现在每次请求对象的时候都调用了构造函数和析构函数,这里大家可以根据实际情况自行选择是象池学否必要调用。如果构造和析构成本也比较高,手撸可以再想办法节省对应的个对开销。亿华云计算

象池学

分享到:

滇ICP备2023006006号-16