4

在 C# 中,我会启动 Stopwatch 类来快速确定某些方法需要多长时间。

这在 C++ 中的等价物是什么?有内置高精度定时器吗?

4

9 回答 9

5

我使用boost::timer来测量操作的持续时间。它提供了一种非常简单的测量方法,同时独立于平台。这是一个例子:

boost::timer myTimer;
doOperation();
std::cout << myTimer.elapsed();

PS为了克服精度误差,测量需要几秒钟的操作会很棒。特别是当您尝试比较几种替代方案时。如果您想测量花费很少时间的东西,请尝试将其放入循环中。例如运行操作 1000 次,然后将总时间除以 1000。

于 2010-02-19T20:07:43.760 回答
4

我之前已经为这样的情况实现了一个计时器:我实际上最终得到了一个具有两种不同实现的类,一个用于 Windows,一个用于 POSIX。

原因是 Windows 具有QueryPerformanceCounter()让您访问非常准确的时钟的功能,该时钟非常适合此类计时。

但是在 POSIX 上这是不可用的,所以我只是使用boost.datetime的类来存储开始和结束时间,然后从中计算持续时间。它提供了一个“高分辨率”计时器,但分辨率未定义,并且因平台而异。

于 2010-02-19T16:27:39.440 回答
3

我使用我自己版本的 Pythontime_it函数。此函数的优点是它可以根据需要重复计算多次以获得有意义的结果。如果计算速度很快,就会重复很多次。最后,您获得所有重复的平均时间。它不使用任何非标准功能:

#include <ctime>

double clock_diff_to_sec(long clock_diff)
{
    return double(clock_diff) / CLOCKS_PER_SEC;
}

template<class Proc>
double time_it(Proc proc, int N=1) // returns time in microseconds
{   
    std::clock_t const start = std::clock();
    for(int i = 0; i < N; ++i)
        proc();
    std::clock_t const end = std::clock(); 
    if(clock_diff_to_sec(end - start) < .2) 
        return time_it(proc, N * 5); 
    return clock_diff_to_sec(end - start) * (1e6 / N);
}

以下示例使用该time_it函数来衡量不同 STL 容器的性能:

void dummy_op(int i)
{
    if(i == -1)
        std::cout << i << "\n";
}

template<class Container>
void test(Container const & c)
{
    std::for_each(c.begin(), c.end(), &dummy_op);
}

template<class OutIt>
void init(OutIt it)
{
    for(int i = 0; i < 1000; ++i)
        *it = i;
}
    
int main( int argc, char ** argv )
{
    {
        std::vector<int> c;
        init(std::back_inserter(c));
        std::cout << "vector: " 
                  << time_it(boost::bind(&test<std::vector<int> >, c)) << "\n";
    }      
    {
        std::list<int> c;
        init(std::back_inserter(c));
        std::cout << "list: "
                  << time_it(boost::bind(&test<std::list<int> >, c)) << "\n";
    }
    {
        std::deque<int> c;
        init(std::back_inserter(c));
        std::cout << "deque: " 
                  << time_it(boost::bind(&test<std::deque<int> >, c)) << "\n";
    }
    {
        std::set<int> c;
        init(std::inserter(c, c.begin()));
        std::cout << "set: " 
                  << time_it(boost::bind(&test<std::set<int> >, c)) << "\n";
    }
    {
        std::tr1::unordered_set<int> c;
        init(std::inserter(c, c.begin()));
        std::cout << "unordered_set: " 
           << time_it(boost::bind(&test<std::tr1::unordered_set<int> >, c)) << "\n";
    }    
}

如果有人好奇,这里是我得到的输出(在发布模式下使用 VS2008 编译):

矢量:8.7168

清单:27.776

双端队列:91.52

套装:103.04

无序集:29.76

于 2010-02-19T16:43:16.387 回答
2

您可以使用ctime 库以秒为单位获取时间。以毫秒为单位获取时间是特定于实现的。 这是一个讨论,探索一些方法来做到这一点。

另请参阅:如何使用 ANSI C 以毫秒为单位测量时间?

于 2010-02-19T16:29:12.277 回答
1

高精度计时器是特定于平台的,因此 C++ 标准没有指定,但有可用的库。请参阅此问题进行讨论。

于 2010-02-19T16:30:19.523 回答
1

我谦虚地提交了我自己的微基准测试迷你库(在 Github 上)。它超级简单——它比自己滚动的唯一优势是它已经为 Windows 和 Linux 实现了高性能计时器代码,并抽象出烦人的样板。

只需传入一个函数(或 lambda)、每次测试运行应调用的次数(默认值:1)和测试运行次数(默认值:100)。返回最快的测试运行(以毫秒为单位测量):

// Example that times the compare-and-swap atomic operation from C++11
// Sample GCC command: g++ -std=c++11 -DNDEBUG -O3 -lrt main.cpp microbench/systemtime.cpp -o bench
#include "microbench/microbench.h"

#include <cstdio>
#include <atomic>

int main()
{
    std::atomic<int> x(0);
    int y = 0;

    printf("CAS takes %.4fms to execute 100000 iterations\n",
        moodycamel::microbench(
            [&]() { x.compare_exchange_strong(y, 0); },  /* function to benchmark */
            100000, /* iterations per test run */
            100 /* test runs */
        )
    );

    // Result: Clocks in at 1.2ms (12ns per CAS operation) in my environment

    return 0;
}
于 2013-07-19T05:46:29.433 回答
0

你可以找到有用的这个类。

使用 RAII 习语,它在调用析构函数时打印构造中给出的文本,并用适当的值填充经过的时间占位符。

使用示例:

int main()
{
   trace_elapsed_time t("Elapsed time: %ts.\n");
   usleep(1.005 * 1e6);
} 

输出:

Elapsed time: 1.00509s.
于 2010-02-20T06:39:50.030 回答
0

这可能是依赖于操作系统的问题,而不是语言问题。

如果您使用的是 Windows,则可以通过GetTickCount()或 GetTickCount64()访问 10 到 16 毫秒的毫秒计时器。只需在开始和结束时调用一次,然后减去。

如果我没记错的话,那是我以前用过的。链接页面还有其他选项。

于 2010-02-19T16:34:12.040 回答
0
#include <time.h>

clock_t start, end;
start = clock();
//Do stuff
end = clock();

printf("Took: %f\n", (float)((end - start) / (float)CLOCKS_PER_SEC));
于 2010-02-19T16:41:45.553 回答