新聞中心
這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
手擼一個對象池,你學(xué)會了嗎?
什么是對象池?
對象的池子,與線程池、內(nèi)存池類似,減少頻繁創(chuàng)建和銷毀對象帶來的成本(特別是消耗資源較大的對象),可用于實現(xiàn)對象的緩存和復(fù)用。這也算是一種設(shè)計模式。

話不多說,直接上代碼:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- struct A {
- A(std::string s) { str_ = std::move(s); }
- void print() { std::cout << str_ << std::endl; }
- std::string str_;
- };
- template
> - 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
- std::shared_ptr
acquireObject(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
pool_; - std::vector
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;
- int main() {
- APool pool;
- for (int i = 0; i < 20; i++) {
- auto x = pool.acquireObject(std::string("hello"));
- x->print();
- }
- return 0;
- }
上面的對象池實現(xiàn)在每次請求對象的時候都調(diào)用了構(gòu)造函數(shù)和析構(gòu)函數(shù),這里大家可以根據(jù)實際情況自行選擇是否必要調(diào)用。如果構(gòu)造和析構(gòu)成本也比較高,可以再想辦法節(jié)省對應(yīng)的開銷。
文章標題:手擼一個對象池,你學(xué)會了嗎?
當前網(wǎng)址:http://m.fisionsoft.com.cn/article/djdhcgj.html


咨詢
建站咨詢
