手?jǐn)]一個(gè)對(duì)象池
時(shí)間:2021-10-11 13:39:52
手機(jī)看文章
掃描二維碼
隨時(shí)隨地手機(jī)看文章
[導(dǎo)讀]點(diǎn)擊上方藍(lán)字關(guān)注我們今天文章的字?jǐn)?shù)不多,主要是分享一下對(duì)象池的實(shí)現(xiàn)!什么是對(duì)象池?對(duì)象的池子,與線程池、內(nèi)存池類似,減少頻繁創(chuàng)建和銷毀對(duì)象帶來(lái)的成本(特別是消耗資源較大的對(duì)象),可用于實(shí)現(xiàn)對(duì)象的緩存和復(fù)用。這也算是一種設(shè)計(jì)模式。話不多說(shuō),直接上代碼:#include#includ...
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>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_ptracquireObject(Args... args) { if (freeObjects_.empty()) { addChunk(); }
T* object{freeObjects_.back()};
new (object) T{std::forward(args)...};
freeObjects_.pop_back();
return std::shared_ptr(object, [this](T* object) { std::_Destroy(object); freeObjects_.push_back(object); }); }
private: std::vector
std::vector
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;
int main() { APool pool; for (int i = 0; i < 20; i ) { auto x = pool.acquireObject(std::string("hello")); x->print(); } return 0;} 上面的對(duì)象池實(shí)現(xiàn)在每次請(qǐng)求對(duì)象的時(shí)候都調(diào)用了構(gòu)造函數(shù)和析構(gòu)函數(shù),這里大家可以根據(jù)實(shí)際情況自行選擇是否必要調(diào)用。如果構(gòu)造和析構(gòu)成本也比較高,可以再想辦法節(jié)省對(duì)應(yīng)的開(kāi)銷。