用windows.h封装一个C++高精度计时器

本文最后更新于:2021年5月9日 下午

# 用windows.h封装一个C++高精度计时器

在Windows上直接调官方给出的API(QueryPerformanceFrequencyQueryPerformanceCounter),在程序里加上windows.h头文件,再通过下面封装好的计时器可以很方便地测试自己写的算法效率。

计时器封装

#include <windows.h>
class Timer{
public:
    Timer()
        : elapsed_(0)
    {
        QueryPerformanceFrequency(&freq_);
    }
    ~Timer(){}
public:
    void start()
    {
        QueryPerformanceCounter(&begin_time_);
    }
    void stop()
    {
        LARGE_INTEGER end_time;
        QueryPerformanceCounter(&end_time);
        elapsed_ += (end_time.QuadPart - begin_time_.QuadPart) * 1000000 / freq_.QuadPart;
    }
    void restart()
    {
        elapsed_ = 0;
        start();
    }
    //微秒
    double elapsed()
    {
        return static_cast<double>(elapsed_);
    }
    //毫秒
    double elapsed_ms()
    {
        return elapsed_ / 1000.0;
    }
    //秒
    double elapsed_second()
    {
        return elapsed_ / 1000000.0;
    }

private:
    LARGE_INTEGER freq_;
    LARGE_INTEGER begin_time_;
    long long elapsed_;
};

计时器使用

Timer t;
t.start();
//do something;
t.stop();
cout << t.elapsed() << " ns" << endl;
cout << t.elapsed_ms() << " ms" << endl;
cout << t.elapsed_second() << " s" << endl;

效果演示

运行代码

int trailingZeroes1(int n) {
	int zero_conut = 0;
	for (; n >= 5; n /= 5, zero_conut += n) {}
	return zero_conut;
}

int trailingZeroes2(int n) {
	return n < 5 ? 0 : (n / 5 + trailingZeroes2(n / 5));
}

int main() {
	int n = 26678;

	Timer t1;
	t1.start();
	int res1 = trailingZeroes1(n);
	printf("\n%d末尾有%d个零\n", n, res1);
	t1.stop();
	printf("for循环方法 耗时:%f ns\n\n", t1.elapsed());

	Timer t2;
	t2.start();
	int res2 = trailingZeroes2(n);
	printf("%d末尾有%d个零\n", n, res2);
	t2.stop();
	printf("递归方法 耗时:%f ns\n", t2.elapsed());
	return 0;
}

在devcpp上使用64位用于性能分析的GCC编译器得到的结果如下。

image-20210509125301299

两种写法时间复杂度都是O(logn),在之前写的LeetCode172 - 阶乘后的零 Py3&C++里两种写法都beat100%了,不知道哪个更快,现在通过这次实验可以看到递归写法还是会快一丢丢的。

参考:C++高精度计时器——微秒级时间统计