排序列表与未排序列表的线性搜索 - 为什么排序较慢?

时间:2014-10-13 06:54:05

标签: c++ list

所以我创建了一些随机的int并将它们放入列表中。我复制了它,然后我对原始列表进行了排序。当我通过排序列表搜索特定项目时,它比我在未排序的副本中的速度慢得多。为什么会这样?这是我使用的代码和最后的一些运行时。

int main(){
   const int SIZE = 100000, MAX_ELM = 10000000;
   list<int> sortedList;
   list<int> unsortedList;
   int indexToFind, itemToFind;

   srand(time_seed());
   indexToFind = SIZE/2;
   //initialize list
   for (int i = 0; i < SIZE; i++){      
      if (i == indexToFind){
         itemToFind = randomNum(0, MAX_ELM);
         sortedList.push_back(itemToFind);
      }
      else
         sortedList.push_back(randomNum(0, MAX_ELM));
   }

   unsortedList = sortedList; //copy ctr
   sortedList.sort();
   clock_t start, end;
   int sortedItemIndex = 0;

   //search for item in sorted list
   start = clock();
   list<int>::iterator it;
   for (it = sortedList.begin(); it != sortedList.end(); ++it){
      if ((*it) == itemToFind){
         break;
      }
      sortedItemIndex++;
   }
   end = clock();

   cout << "index: " << sortedItemIndex << "  item: " << itemToFind << endl; 
   cout << (double)(end - start) / (double)CLOCKS_PER_SEC << endl << endl;

   //unsorted
   start = clock();
   for (it = unsortedList.begin(); it != unsortedList.end(); ++it){
      if ((*it) == itemToFind)
         break;
   }
   end = clock();

   cout << "index: " << indexToFind << "  item: " << itemToFind << endl;
   cout << (double)(end - start) / (double)CLOCKS_PER_SEC << endl;

}

以下是我播种rand()的功能,虽然我认为它们并不重要

int randomNum(int min, int max){

   return rand() * (1.0 / (RAND_MAX + 1.0)) * (max - min);
}

unsigned time_seed(){ // implementation from online
   time_t now = time(NULL);
   unsigned char *p = (unsigned char *)&now;
   unsigned seed = 0;
   size_t i;

   for (i = 0; i < sizeof now; i++)
      seed = seed * (UCHAR_MAX + 2U) + p[i];

   return seed;
}

我的运行时间是:

sortedList - index:44315 item:4439392 time:0.047 sec

未分类 - 索引:50000项目:4439392时间:0.028秒

2 个答案:

答案 0 :(得分:3)

我对这个主题有点生疏,但据我所知,c ++列表是双向链表,这意味着无法保证数据在内存中是连续的。 分配给两个列表的内存最初是相当(如果不是完全)连续的,这很可能意味着CPU不必非常寻找RAM。 由于列表的性质,对它进行排序不会物理地移动数据,而只是更新每个元素指向的内容。因此,当您对列表进行排序时,元素将指向内存中的所有位置,这意味着CPU将不得不为几乎每个操作获取新的RAM。

通常这不是一个大问题,但是当你平均重复它50000次时会浪费很多CPU周期而只是等待RAM响应等。

答案 1 :(得分:0)

我真的没有看到您的代码有任何问题,但测试的顺序可能很重要。特别是在如此短的运行时间内,特别是如果您的计算机运行时处理器能够动态地改变其性能状态。

许多英特尔处理器都配备了名为turbo boost的技术,当有性能需求时,它基本上使处理器更强大,而且为了节省能源,在不需要时可以恢复到较低的性能状态。为此它。有关详细信息,请参阅this wiki site

结论 - 尝试更改测试顺序或/并将处理器调控器设置为性能,并增加测试集的大小。 0.0 ...运行时间非常短,许多奇怪的现象可能会生效。

另外考虑将整数存储在更方便的东西中,例如vector。在列表中存储整数似乎是浪费空间,除非你有充分的理由这样做。