【问题标题】:Wrong output with 'chrono' library'chrono' 库的错误输出
【发布时间】:2019-11-28 10:36:20
【问题描述】:

我试图计算在执行插入排序函数期间经过的时间。所以我做了如下。 附言- 功能正常运行并对所有数字进行排序。 编译器 - GCC 窗户

    auto start = chrono::steady_clock::now();
    insertionSort(arr,1000);
    auto end = chrono::steady_clock::now();

    auto diff = start - end; // gives 0 
    auto diff = end - start ; // still zero

    cout << chrono::duration <double, nano> (diff).count() << " ns" << endl;

首先我尝试输入 100,它给了我0 ms,然后我将它更改为ns,它仍然给了零。然后我将输入增加到1000。但遗憾的是输出仍然为零。 这是编写chrono的正确方法吗? 有人建议尝试 chrono::high_resolution_clock 它仍然给了我 0ns。

或者你们可以建议的任何方法来计算函数的时间。

更新 - 所以我一直在寻找解决方案,所以我发现如果做类似的事情有时会产生结果。

    auto start = chrono::high_resolution_clock::now();
    insertionSort(arr,1000);
    auto end = chrono::high_resolution_clock::now();

    auto diff = end - start;

    cout << chrono::duration <double, nano> (diff).count() << " ns" << endl;


    ofstream  write;
    write.open("sort.txt");
    if(write)
    {
        for(int i = 0 ; i < 1000 ; ++i)
        {
            write<<arr[i]<<endl;
        }
    }
    else{
        cout<<"Unable to open file.\n";
    }




我现在尝试将它写入文件,如果我选择nano second,它会给我结果。 但如果我选择mili,它仍然为零。

这是否意味着插入排序速度非常快,C++ 甚至无法测量它?

这是可重现的代码。

#include<iostream>
#include<fstream>
#include<chrono>
using namespace std;

void readData();
void insertionSort(int * , int );
void readData()
{

    int arr[1000];
    ifstream read;
    read.open("sort.txt",ios::binary);
    if(read)
    {
        int i = 0;
        int temp;
        while(read>>temp)
        {
            arr[i] = temp;
            ++i;
        }
        read.close();

    }
    else{
        cout<<"Unable to open file.\n";
    }


    auto start = chrono::high_resolution_clock::now();
    insertionSort(arr,1000);
    auto end = chrono::high_resolution_clock::now();

    auto diff = end - start;

    cout << chrono::duration <double, nano> (diff).count() << " ns" << endl;

    ofstream  write;
    write.open("sort.txt");
    if(write)
    {
        for(int i = 0 ; i < 1000 ; ++i)
        {
            write<<arr[i]<<endl;
        }
    }
    else{
        cout<<"Unable to open file.\n";
    }

}
void insertionSort(int *arr , int size)
{
    for(int i = 1 ; i < size ; ++i)
    {
        int key = arr[i];
        int j = i -1 ;
        while(j>= 0 && arr[j]> key)
        {
            arr[j+1] = arr[j];
            j--;
        }
        arr[++j] = key;
    }

}
int main()
{
    readData();
    return 0;
}

【问题讨论】:

  • 试试chrono::high_resolution_clock
  • 这可能是经过优化的东西。例如,gcc 有时会在编译时计算所有内容,从而消除任何运行时计算。您应该使用随机数或其他东西进行性能测试。
  • @tkausl 试过但还是零:-(
  • auto diff = start - end; 可能是auto diff = end - start;
  • @ALX23z 你能详细解释一下你在上面的评论中写了什么吗?

标签: c++


【解决方案1】:

使用正确的模板参数来标记你想要的毫秒数:

std::chrono::duration<double, std::milli> diff = end - start ; // still zero
cout << diff.count() << " ms" << endl;

如果它仍然为零,也许你的操作太快了,不到 1 毫秒就可以完成?如今,对 1000 个元素的数组进行排序非常快。放大或重复几次。

对于 10000 个元素,它开始返回一些大于 0 的值。 你的环境是什么?也许在你的情况下 high_resolution_clock 不可用...... Time measurements with High_resolution_clock not working as intended

顺便说一句,我也有 50% 的时间为 0。

【讨论】:

  • 我将其更改为纳秒,但仍为零。
  • 顺便说一句,编写 std::nano 需要什么。我已经添加了命名空间标准。
  • @vll 是,如果时钟坏了
  • @NikhilSharma 不需要,但看看here
【解决方案2】:

就像您在 Windows 上一样,您可以使用QueryPerformanceFrequency()。它将为您提供系统在一秒钟内执行的滴答数。因此,您可以使用它来计算系统时钟的实际精度:

#include <Windows.h>

int main() {
    LARGE_INTEGER freq;
    QueryPerformanceFrequency(&freq);
    std::cout << 1.e9 / freq.QuadPart << "ns accuracy" << std::endl;
}

所有尝试测量比这更快的东西都会得到 0。任何尝试测量大致相同数量级的东西都是不准确的。

例如,在我的系统上,上面的代码打印100ns accuracy。 如果我运行你的代码,它大部分时间会打印1100ns,有时会打印1200ns,有时会打印1000ns。请注意,这始终是精度的倍数。

克服这个问题的一种常见方法是多次运行有问题的代码并取平均值,如下所示:

constexpr int runs = 2000;

auto start = std::chrono::steady_clock::now();
for (int i = 0; i < runs; ++i)
    insertionSort(arr,1000);
auto end = std::chrono::steady_clock::now();

auto diff = end - start;

cout << std::chrono::duration <double, std::nano> (diff).count() / runs << " ns" << endl;

在我的系统上打印1016.7ns

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多