时间测量在 C++ 中不起作用

Posted

技术标签:

【中文标题】时间测量在 C++ 中不起作用【英文标题】:Time measurement not working in C++ 【发布时间】:2015-12-17 13:11:33 【问题描述】:

我正在尝试对线性排序等简单算法进行运行时测量。问题是无论我做什么,时间测量都不会按预期工作。无论我使用什么问题大小,我都会得到相同的搜索时间。我和其他试图帮助我的人都同样感到困惑。

我有一个如下所示的线性排序函数:

// Search the N first elements of 'data'.
int linearSearch(vector<int> &data, int number, const int N) 
    if (N < 1 || N > data.size()) return 0;

    for (int i=0;i<N;i++) 
        if (data[i] == number) return 1;
    

    return 0;

我尝试使用 C++11 中的 time_t 和 chrono 进行时间测量,但没有任何运气,除了更多的小数。这就是我现在搜索时的样子。

vector<int> listOfNumbers = large list of numbers;

for (int i = 15000; i <= 5000000; i += 50000) 
    const clock_t start = clock();

    for (int a=0; a<NUMBERS_TO_SEARCH; a++) 
        int randNum = rand() % INT_MAX;
        linearSearch(listOfNumbers, randNum, i);
    

    cout << float(clock() - start) / CLOCKS_PER_SEC << endl;

结果? 0.126, 0.125, 0.125, 0.124, 0.124, ...(相同的值?)

我已经在 VC++、g++ 和不同的计算机上尝试过代码。

首先,我认为是我对搜索算法的实现有问题。但是像上面这样的线性排序不能变得更简单,它显然是 O(N)。即使问题规模增加了这么多,时间怎么可能一样呢?我不知道该怎么办。

编辑 1: 其他人可能会解释为什么会这样。但它实际上在更改后在发布模式下工作: if (data[i] == number)

收件人:

if (data.at(i) == number)

我不知道为什么会这样,但线性搜索可以在更改后正确测量时间。

【问题讨论】:

data 有足够的元素吗? 要搜索的数据不是出现在向量的早期吗? 向量有大约 570 万个元素。现在数据是按排序顺序排列的素数。但我也尝试使用具有相同结果的随机数据对其进行初始化。 如果向量的所有元素都是1并且搜索目标(randNum)都是2怎么办? 仅将数据更改为 1s 并仅搜索 2s 后,我得到了相同的时间,介于 0.124 和 0.127 之间。 【参考方案1】:

大约恒定的执行时间的原因是编译器能够优化掉部分代码。

具体看这部分代码:

  for (int a=0; a<NUMBERS_TO_SEARCH; a++) 
      int randNum = rand() % INT_MAX;
      linearSearch(listOfNumbers, randNum, i);
  

当使用 g++5.2 和优化级别 -O3 编译时,编译器可以完全优化掉对 linearSearch() 的调用。这是因为无论是否调用该函数,代码的结果都是相同的。 linearSearch 的返回值没有在任何地方使用,并且该函数似乎没有副作用。所以编译器可以删除它。

您可以交叉检查和修改内部循环如下。执行时间不应改变:

  for (int a=0; a<NUMBERS_TO_SEARCH; a++) 
      int randNum = rand() % INT_MAX;
      // linearSearch(listOfNumbers, randNum, i);
  

循环中剩下的是对rand() 的调用,这似乎是您要测量的。将data[i] == number 更改为data.at(i) == number 时,对linearSearch 的调用不是无副作用的,因为at(i) 可能会引发超出范围的异常。所以编译器并没有完全优化掉linearSearch 代码。但是,在 g++5.2 中,它仍然会内联它并且不会进行函数调用。

【讨论】:

【参考方案2】:

clock() 正在测量 CPU 时间,也许你想要 time(NULL)?检查这个issue

【讨论】:

试过了,但它仍然给我相同的值。无论我进行多少次迭代,它们的时间都差不多。【参考方案3】:

start 应该在 for 循环之前。在您的情况下,start 每次迭代都不同,它在 ... 之间是恒定的。

const clock_t start = clock(); for (int i = 15000; i <= 5000000; i += 50000) ...

【讨论】:

那是因为我会测量许多不同尺寸的时间。首先我为 N = 15000 然后 N = 65000 等直到 N = 5000000。里面的循环是我为每个 N 搜索多少个数字。

以上是关于时间测量在 C++ 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

3D(7 参数)Helmert 变换在 Python 中不起作用

相对路径在 Xcode C++ 中不起作用

Char 数组在 C++ 中不起作用

为啥使用命名空间在我的 C++ 项目中不起作用?

为啥 C++ CLI 索引属性在 C# 中不起作用?

地图删除器在 C++ 中不起作用?