c – Boost池分配器比新的慢

c – Boost池分配器比新的慢,第1张

概述所以我基于boost池创建了这个容器分配器memory_pools类: memory_pools.hpp #ifndef MEMORY_POOL_HPP# define MEMORY_POOLS_HPP// boost# include <boost/pool/pool.hpp># include <boost/unordered_map.hpp>template<typename 所以我基于boost池创建了这个容器分配器memory_pools类:

memory_pools.hpp

#ifndef MEMORY_POol_HPP# define MEMORY_POolS_HPP// boost# include <boost/pool/pool.hpp># include <boost/unordered_map.hpp>template<typename ElementType>class   memory_pools{public:  template <typename>  frIEnd class memory_pools;private:  using pool = boost::pool<>;public:  using value_type = ElementType;  using pointer = value_type*;  using const_pointer = const value_type*;  using reference = value_type&;  using const_reference = const value_type&;  using size_type = pool::size_type;  using difference_type = pool::difference_type;public:  template<typename OtherElementType>  struct rebind  {    using other = memory_pools<OtherElementType>;  };public:  memory_pools();  template<typename SourceElement>  memory_pools(const memory_pools<SourceElement>&);public:  pointer   allocate(const size_type n);  voID  deallocate(const pointer ptr,const size_type n);  template<typename... Args>  voID  construct(pointer,Args...);  voID  destroy(pointer);public:  bool  operator==(const memory_pools&);  bool  operator!=(const memory_pools&);private:  using pools_map = boost::unordered_map<std::size_t,std::shared_ptr<pool>>;private:  std::shared_ptr<pools_map>      pools_map_;  std::shared_ptr<pool>           pool_;};# include <memory_pools.ipp>#endif

memory_pools.ipp

#ifndef MEMORY_POolS_IPP# define MEMORY_POolS_IPPtemplate<typename ElementType>memory_pools<ElementType>::memory_pools()  :  pools_map_(std::make_shared<pools_map>             (pools_map             {               std::make_pair                 (sizeof(ElementType),make_shared<pool>(sizeof(ElementType)))             })),pool_(pools_map_->at(sizeof(ElementType))){}template<typename ElementType>template<typename SourceElement>memory_pools<ElementType>::memory_pools(const memory_pools<SourceElement>& rebinded_from)  :  pools_map_(rebinded_from.pools_map_),pool_(pools_map_->insert        (std::make_pair(sizeof(ElementType),make_shared<pool>(sizeof(ElementType)))).first->second)  {  }template<typename ElementType>typename memory_pools<ElementType>::pointer memory_pools<ElementType>::allocate(const size_type n){  pointer ret = static_cast<pointer>(pool_->ordered_malloc(n));  if ((!ret) && n)    throw std::bad_alloc();  return (ret);}template<typename ElementType>voID        memory_pools<ElementType>::deallocate(const pointer ptr,const size_type n){  pool_->ordered_free(ptr,n);}template<typename ElementType>template<typename... Args>voID        memory_pools<ElementType>::construct(pointer ptr,Args... args){  new (ptr) ElementType(std::forward<Args>(args)...);}template<typename ElementType>voID        memory_pools<ElementType>::destroy(pointer ptr){  ptr->~ElementType();}template<typename ElementType>bool        memory_pools<ElementType>::operator==(const memory_pools& rhs){  return (pools_map_ == rhs.pools_map_);}template<typename ElementType>bool        memory_pools<ElementType>::operator!=(const memory_pools& rhs){  return (pools_map_ != rhs.pools_map_);}#endif

然后我用它测试它:

#include <memory_pools.hpp>int     main(voID){  using pools_type = memory_pools<std::pair<const int,int>>;  pools_type    pools;  boost::unordered_map<int,int,boost::hash<int>,std::equal_to<int>,pools_type>      map;  //boost::unordered_map<int,std::equal_to<int>>      map;  for (unsigned int i = 0; i < 20000; ++i)    {      map[i] = i + 1;    }  return (0);}

使用macOSX 10.10上的clang3.5,我得到了:

$time ./a.outreal    0m1.873suser    0m1.850ssys     0m0.009s

而当我发布时:

#include <memory_pools.hpp>int     main(voID){  using pools_type = memory_pools<std::pair<const int,int>>;  pools_type    pools;  //boost::unordered_map<int,pools_type>      map;  boost::unordered_map<int,std::equal_to<int>>      map;  for (unsigned int i = 0; i < 20000; ++i)    {      map[i] = i + 1;    }  return (0);}

我有:

$time ./a.outreal    0m0.019suser    0m0.016ssys     0m0.002s

使用boost pool的内存分配应该是那么慢还是我的测试由于某种原因无效?

编辑

在Carmeron的评论之后,我添加了-O3和-DNDEBUG标志,现在我有:

$time ./a.outreal    0m0.438suser    0m0.431ssys     0m0.003s

对于memory_pools版本,以及:

$time ./a.outreal    0m0.008suser    0m0.006ssys     0m0.002s

对于标准分配器版本.

问题仍然存在,它是否正常更慢?

解决方法 我从未使用过Boost的池代码,甚至没有使用它.但我一般都知道有关内存池的一些事情,我不希望测试中的内存池优于malloc.

要理解这一点,您必须首先了解如果尚未实现malloc和free的实现方式.这个问题的答案似乎提供了一个非常好的总结:How do malloc() and free() work?

内存碎片是malloc()和free()的一个难题,而且没有简单,快速的解决方案.但是如果你可以保证你的所有分配都是相同的大小那么容易得多:这就是内存池可以获胜的方式.但是你的测试不涉及大量的内存碎片,并且可能根本没有释放大量内存.因此,在此测试中,malloc()获胜,并且池丢失.要优化您的测试,您可能会混合一堆删除,例如:

// Allocate 10,000 things// Loop 10 times://   Allocate 1,000 things//   Delete 1,000 things

说了这么多,如果你真的想知道为什么一段特定的代码按照它的方式执行,你应该对它进行分析.思考一段代码为什么以某种特定方式运行的理论是有用的,但你也必须测试你的理论.

总结

以上是内存溢出为你收集整理的c – Boost池分配器比新的慢全部内容,希望文章能够帮你解决c – Boost池分配器比新的慢所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1243068.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存