C++ 排序列表上的线性搜索与未排序列表上的线性搜索——为什么排序较慢?

C++ 排序列表上的线性搜索与未排序列表上的线性搜索——为什么排序较慢?,c++,list,C++,List,所以我创建了一些随机整数并将它们放入列表中。我复制了一份,然后对原始列表进行排序。当我通过已排序列表搜索特定项时,它比我在未排序副本中搜索时慢得多。为什么会发生这种情况?下面是我使用的代码和最后的一些运行时 int main(){ const int SIZE = 100000, MAX_ELM = 10000000; list<int> sortedList; list<int> unsortedList; int indexToFind, it

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

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;

}
intmain(){
常数int SIZE=100000,最大值=10000000;
列表分类列表;
未分类列表;
int indexToFind,itemToFind;
srand(time_seed());
IndextofId=大小/2;
//初始化列表
对于(int i=0;iCUT

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


通常这不是什么大不了的事情,但是当你平均重复50000次的时候,就是等待RAM响应的浪费了很多CPU周期等等。

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


通常这不是什么大不了的事情,但是当你平均重复50000次的时候,就是等待RAM响应的浪费了很多CPU周期等等。

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


通常这不是什么大不了的事情,但是当你平均重复50000次的时候,就是等待RAM响应的浪费了很多CPU周期等等。

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


一般来说,这并不是什么大问题,但当你平均重复50000次时,等待RAM响应就浪费了大量CPU周期。

我真的看不出你的代码有什么问题,但是测试的顺序可能很重要。尤其是在运行时间如此短的情况下,尤其是当你的计算机运行的是p能够动态更改其性能状态的处理器

许多英特尔处理器都配备了名为
turbo boost
的技术,该技术基本上可以使处理器在有性能需求时更强大,而在不再需要时,为了节省能源,处理器会返回到性能较低的状态。有关更多信息,请参阅

因此,总结-尝试更改测试顺序或/或将处理器调控器设置为性能,同时增加测试集的大小。0.0…运行时间非常低,许多奇怪的现象可能会产生影响


也可以考虑把你的整数存储在一些更方便的东西中,比如向量。在列表中存储整数似乎是非常浪费空间的,除非你有一个很好的理由这样做。

< P>我不认为你的代码有任何问题,但是测试的顺序可能很重要。您的计算机运行的处理器能够动态更改其性能状态

许多英特尔处理器都配备了名为
turbo boost的技术,这项技术基本上可以在有性能需求的情况下使处理器更强大,而不是为了节约能源而倒退
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;
}