Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 队列算法_C++_Algorithm_Performance_Queue - Fatal编程技术网

C++ 队列算法

C++ 队列算法,c++,algorithm,performance,queue,C++,Algorithm,Performance,Queue,我正在尝试创建一个基于链表的队列,用于快速操作,这就是我所拥有的: template< typename T, template< typename > class Allocator = default_allocator > class fast_queue { public: typedef T element_type; typedef T* element_ptr; private: typedef struct e_n

我正在尝试创建一个基于链表的队列,用于快速操作,这就是我所拥有的:

template< typename T, 
          template< typename > class Allocator = default_allocator
>
class fast_queue
 {
 public:
  typedef T element_type;
  typedef T* element_ptr;

 private:
  typedef struct e_node
  {
   element_type val;
   e_node * next;
  }node_type;
  typedef node_type * node_ptr;
  node_ptr parent;
  node_ptr child;
  int      m_size;
  typedef Allocator< node_type > allocator_type;

 public:
  fast_queue()
   : parent( 0 )
   , child( 0 )
   , m_size( 0 )
  {
  }

  ~fast_queue() {
   this->clear();
  }

  void push(element_type& i)
  {
   node_ptr n = allocator_type::alloc();
   n->val = i;
   n->next = (node_ptr)0;
   if(child) {
    child->next = n;
   } else {
    parent = n;
   }
   child = n;
   m_size++;
  }

  element_type pop()
  {
   element_type ret = parent->val;
   node_ptr p = parent;
   parent = parent->next;
   m_size--;
   allocator_type::dealloc(p);
   return ret;
  }

  inline int size() const 
  {
   return m_size;
  }

  inline bool empty() const
  {
   return (m_size == 0);
  }

  void clear() 
  {
   while(!empty()) {
    pop();
   }
   child = 0;
  }
 };
template类分配器=默认分配器
>
类快速队列
{
公众:
类型定义T元素_类型;
类型定义T*元素\u ptr;
私人:
类型定义结构e_节点
{
元素_型val;
e_节点*下一步;
}节点类型;
typedef node_type*node_ptr;
节点ptr父节点;
节点ptr子节点;
国际货币单位大小;
typedef分配器<节点类型>分配器类型;
公众:
快速队列()
:家长(0)
,儿童(0)
,m_尺寸(0)
{
}
~fast_queue(){
这个->清除();
}
无效推力(元件类型和i)
{
node_ptr n=分配器_type::alloc();
n->val=i;
n->next=(node_ptr)0;
如果(儿童){
child->next=n;
}否则{
父代=n;
}
child=n;
m_size++;
}
元素类型pop()
{
元素类型ret=父元素->值;
节点p=父节点;
父项=父项->下一步;
m_尺寸--;
分配器类型:dealloc(p);
返回ret;
}
内联int size()常量
{
返回m_大小;
}
内联bool empty()常量
{
返回值(m_size==0);
}
无效清除()
{
而(!empty()){
pop();
}
child=0;
}
};
非常简单,现在我遇到的问题是clear()函数。 释放队列中的所有节点似乎花费了太多的时间(7秒)。 所以问题是,什么可能是更好的算法?我试图理解MSVC对std::deque的实现,但代码太庞大,我无法理解

编辑: 队列应该是通用的,允许对任意类型的数据进行排队。 这是我的测试代码(Windows)

DWORD time1=timeGetTime();
快速队列;
对于(int i=0;i<100000;i++){
排队推送(i);
}
queue.clear();

cout正如其他人所说,内存分配/释放是这里最大的性能问题


我建议你试试。如果默认大小设置得足够高,则在其生存期内只会导致一次内存分配。

正如其他人所建议的,内存分配/释放是这里最大的性能问题


我建议你试试。如果默认大小设置得足够高,则在其生存期内只会导致一次内存分配。

您正在构建一个链表。deque实现在每个分配中存储很多很多元素。但是,您可以分别为每个元素分配和取消分配。这就是为什么你的队伍排得这么慢


除此之外,该标准的队列接口还指出,您应该采用完整的分配器类型,而不是模板,尽管满足该标准分配器要求的现实是,它无论如何都必须是模板。

您正在构建一个链接列表。deque实现在每个分配中存储很多很多元素。但是,您可以分别为每个元素分配和取消分配。这就是为什么你的队伍排得这么慢


除此之外,该标准的队列接口还指出,您应该采用完整的分配器类型,而不是模板,尽管满足该标准分配器要求的现实是,无论如何它必须是一个模板。

通过更改push/pop/clear算法,您可以做的不多,因为95%的时间用于节点的分配和解除分配。但是你可以做一些事情:

1) 为节点使用某种内存池。您可以使用池分配器(boost::pool_alloc是一个很好的分配器,如果您不想实现自己的分配器),也可以在队列类中使用内部节点缓存。因此,不删除节点,只需将其推送到节点缓存,创建节点时,从缓存中弹出它们


2) 在一个节点中存储多个项目。例如,如果一个节点中有8个项目,则每8次推送/弹出只需分配/解除分配一次。当然,这需要稍微复杂一些的代码;除了有指向head和tail节点的指针外,还需要它们的索引变量来跟踪实际使用的项目数量

通过更改push/pop/clear算法,您可以做的不多,因为95%的时间用于节点的分配和解除分配。但是你可以做一些事情:

1) 为节点使用某种内存池。您可以使用池分配器(boost::pool_alloc是一个很好的分配器,如果您不想实现自己的分配器),也可以在队列类中使用内部节点缓存。因此,不删除节点,只需将其推送到节点缓存,创建节点时,从缓存中弹出它们


2) 在一个节点中存储多个项目。例如,如果一个节点中有8个项目,则每8次推送/弹出只需分配/解除分配一次。当然,这需要稍微复杂一些的代码;除了有指向head和tail节点的指针外,还需要它们的索引变量来跟踪实际使用的项目数量

我不得不拿出所有分配器的东西来编译它(在g++4.40下),但它很快就可以运行了。即使我推送100倍多的元素,填充队列只需要大约半秒钟,清除队列只需要半秒钟。你试过使用new和delete吗?

我不得不拿出所有分配器的东西来编译它(在g++4.40下),但它很快就会运行。即使我推送100倍多的元素,填充队列只需要大约半秒钟,清除队列只需要半秒钟。您尝试过使用“新建”和“删除”吗?

请提供更多信息。您通常希望执行哪些操作?您的数据集有多大?您希望在容器中存储哪些数据?没有一个容器在所有情况下都是最好的,所以你需要选择一个适合你想要做的。我编辑了这个问题,我意识到没有什么是在所有情况下都是最好的,我只是想找到一个比l更好的算法
DWORD time1 = timeGetTime();
fast_queue<int> queue;

for(int i = 0; i < 100000; i++) {
    queue.push(i);
}
queue.clear();
cout << "Test time: " << (int)(timeGetTime() - time1) << " milliseconds" << endl;