查看原文
其他

手撸一个对象池

程序喵大人 程序喵大人 2022-08-22


点击上方蓝字关注我们


今天文章的字数不多,主要是分享一下对象池的实现!



什么是对象池?

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


话不多说,直接上代码:

#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;}

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


打完收工!


从未见过把内存玩的如此明白的文章(推荐大家都来看看)

2021-09-19

会吹牛逼真的很重要

2021-09-13

写出高效代码的12条建议

2021-08-16

关于多线程,我给出13点建议

2021-08-04

推荐几个开源库

2021-08-12

累够呛!整理了一份C++学习路线图!

2021-07-30

如何设计结构体

2021-07-22



分享

收藏

点赞

在看


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存