定时功能:双返0毫秒

Timing Functions: Double Returning 0 MS

本文关键字:0毫秒 双返 功能 定时      更新时间:2023-10-16

我正在为一个类的数据结构编写一个深入的测试程序。我正在计算函数执行所需的时间,并将它们存储在数组中以备日后打印。为了再次检查它是否有效,我决定立即打印它,但我发现它不起作用。

这是我获取时间并将其存储在结构中的数组中的代码。

void test1(ArrayLinkedBag<ItemType> &bag,TestAnalytics &analytics){
clock_t totalStart;
clock_t incrementalStart;
clock_t stop; //Both timers stop at the same time;
// Start TEST 1
totalStart = clock();
bag.debugPrint();
cout << "Bag Should Be Empty, Checking..." << endl;
incrementalStart = clock();
checkEmpty<ItemType>(bag);
stop = clock();
analytics.test1Times[0] = analytics.addTimes(incrementalStart,stop);
analytics.test1Times[1] = analytics.addTimes(totalStart,stop);
cout << analytics.test1Times[0] << setprecision(5) << "ms" << endl;
std::cout << "Time: "<< setprecision(5)  << (stop - totalStart) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
cout << "===========================================" << endl; //So I can find the line easier
}

这是我在数组中进行计算的代码,该函数位于TestAnalytics结构中

double addTimes(double start, double stop){
return (stop - start)/ (double)(CLOCKS_PER_SEC/1000);
}

以下是我得到的输出片段:

Current Head: -1
Current Size: 0
Cell: 1, Index: 0, Item: 6317568, Next Index: -2
Cell: 2, Index: 1, Item: 4098, Next Index: -2
Cell: 3, Index: 2, Item: 6317544, Next Index: -2
Cell: 4, Index: 3, Item: -683175280, Next Index: -2
Cell: 5, Index: 4, Item: 4201274, Next Index: -2
Cell: 6, Index: 5, Item: 6317536, Next Index: -2
Bag Should Be Empty, Checking...
The Bag Is Empty
0ms
Time: 0 ms
===========================================

我正试图根据这个网站上的不同帖子来计算时间。我在UNIX系统上使用clang编译器。这个数字可能仍然太小而无法显示在0以上吗?

除非您使用旧的(C++11之前的)编译器/库,否则我会使用<chrono>标头中的函数:

template <class ItemType>
void test1(ArrayLinkedBag<ItemType> &bag){
using namespace std::chrono;
auto start = high_resolution_clock::now();
bag.debugPrint();
auto first = high_resolution_clock::now();
checkEmpty(bag);
auto stop = high_resolution_clock::now();
std::cout << " first time: " << duration_cast<microseconds>(first - start).count() << " usn";
std::cout << "second time: " << duration_cast<microseconds>(stop - start).count() << " usn";
}

有些部分有点冗长(说得好一点),但它仍然运行得相当好。duration_cast支持低至(至少)nanoseconds的差异类型,这通常足以对相对较小/快速的代码片段进行计时(尽管不能保证它使用纳秒精度的计时器)。

除了Jerry的好答案(我已经投了赞成票)之外,我还想添加一些可能有用的信息。

对于计时,我建议steady_clock而不是high_resolution_clock,因为steady_clock保证在计时过程中不会调整(尤其是向后调整)。现在在Visual Studio和clang上,这不可能发生,因为high_resolution_clocksteady_clock是完全相同的类型。但是,如果您使用的是gcc,则high_resolution_clocksystem_clock的类型相同,可以随时进行调整(例如通过NTP校正)。

但如果你使用steady_clock,那么在每个平台上你都有一个类似秒表的计时器:不适合告诉你一天中的时间,但也不会在不合时宜的时候被更正。

此外,如果您使用我的免费、开源、仅头部的<chrono>扩展库,它可以以更友好的方式流式输出持续时间,而无需使用duration_cast.count()。它将打印出持续时间单位以及值。

最后,如果您连续多次调用steady_clock::now()(其间没有任何内容),并打印出差异,那么您就可以了解您的实现对时间的精确性。它能计时飞秒这样短的东西吗?可能不会。它像毫秒一样粗糙吗?我们希望不会。

把这些放在一起,下面的程序是这样编译的:

clang++ test.cpp -std=c++14 -O3 -I../date/include

程序:

#include "date/date.h"
#include <iostream>
int
main()
{
using namespace std::chrono;
using date::operator<<;
for (int i = 0; i < 100; ++i)
{
auto t0 = steady_clock::now();
auto t1 = steady_clock::now();
auto t2 = steady_clock::now();
auto t3 = steady_clock::now();
auto t4 = steady_clock::now();
auto t5 = steady_clock::now();
auto t6 = steady_clock::now();
std::cout << t1-t0 << 'n';
std::cout << t2-t1 << 'n';
std::cout << t3-t2 << 'n';
std::cout << t4-t3 << 'n';
std::cout << t5-t4 << 'n';
std::cout << t6-t5 << 'n';
}
}

我在macOS上的输出:

150ns
80ns
69ns
53ns
63ns
64ns
88ns
54ns
66ns
66ns
59ns
56ns
59ns
69ns
76ns
74ns
73ns
73ns
64ns
60ns
58ns
...