C ++设置比较慢?

时间:2013-06-02 08:07:05

标签: c++ data-structures

我必须使用一种数据结构,使元素保持某种顺序 我可以查询最少元素,也可以有效地插入新元素。所以我选择了 set ( C++ stl)插入需要log(n)时间,删除最少元素需要log(n)

所以我写了以下程序:

#include<iostream>
#include<set>
#include<stdio.h>
using namespace std;
int main()
{
   set<int>s1,s2;
   set<int>::iterator it;
   int tmp,i;
   for(i=1;i<=1000000;i++)s1.insert(i);
   for(i=1;i<=1000000;i++)
   {
      it=s1.begin();
      s2.insert(*it);
      s1.erase(s1.begin());
   }
return 0;
}

但是我的机器上需要1.67秒( i core 3 )我预计会少O(log(1000000)*1000000),即2*10^7我尝试优先级队列< / em>它也给了我相同的表现。那么我应该实现自己的以使其更快或有其他方式吗?

3 个答案:

答案 0 :(得分:7)

您正在做的是平衡二叉搜索树可能遭受的最困难的事情之一。您将插入项目保留在树的最右侧,并从最左侧继续删除项目,使树始终必须重新平衡。

答案 1 :(得分:4)

有一个名为priority_queue的模板可以更好地处理您描述的工作负载。它是最大堆,而不是最小堆,但它允许您将自定义比较器作为模板参数传递。它是通过在底层容器上维护堆排序来实现的,该容器通常是vector

set实现为平衡二叉树。这意味着每次插入和查询都会执行log2(n)高度非本地内存访问;把它想象成log2(n)缓存未命中。堆好多了。这些在现代处理器上尤其粗糙,当你驯服你的内存访问模式时,看到一个大的恒定因子加速并不罕见。

答案 2 :(得分:0)

class heap
{
   int heap[1000001],siz;
   public:
   int ini()
   {
      siz=0;
   }
   int size()
   {
      return siz;
   }
   int top()
   {
     return heap[1];
   }
  void insert(int num)
  {
     siz++;
     heap[siz]=num;
     int pos=siz,tmp;
     while(pos>1)
     {
    if(heap[pos]<heap[pos/2])
    {
       tmp=heap[pos];
       heap[pos]=heap[pos/2];
       heap[pos/2]=tmp;
    }
    else break;
     }
  }
  void del()
  {
     if(siz==1)
     {
    siz=0;
    return;
     }
     heap[1]=heap[siz];
     siz--;
     int pos=1,tmp;
     while(2*pos<=siz)
     {
    if(2*pos+1<=siz)
    {
       if(heap[2*pos]<=heap[2*pos+1])
       {
          if(heap[pos]>heap[2*pos])
          {
         tmp=heap[pos];
         heap[pos]=heap[2*pos];
         heap[2*pos]=tmp;
         pos=2*pos;
          }
          else break;
       }
       else if(heap[2*pos+1]<=heap[2*pos])
       {
          if(heap[pos]>heap[2*pos+1])
          {
         tmp=heap[pos];
         heap[pos]=heap[2*pos+1];
         heap[2*pos+1]=tmp;
         pos=2*pos+1;
          }
          else break;
       }
    }
    else 
    {

       if(heap[pos]>heap[2*pos])
       {
          tmp=heap[pos];
          heap[pos]=heap[2*pos];
          heap[2*pos]=tmp;
          pos=2*pos;
       }

       else break;

    }
     }
  }

};
int main()
{
   int i,tmp;
   heap a1,a2;
   a1.ini();a2.ini();
   for(i=1;i<=1000000;i++)a1.insert(i);
   for(i=1;i<=1000000;i++)
   {
      tmp=a1.top();
      a2.insert(tmp);
      a1.del();
   }
}

我实现了自己的堆并且在现在0.25秒内完成了同样的操作。我猜它确实是分配和释放内存使得设置变慢。