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;