zoukankan      html  css  js  c++  java
  • C++中衡量代码运行时间的方法

    C++11提供了 chrono 库,我们可以用它提供的工具来衡量代码的运行时间。我总结了三种方式。

    首先,最简单的方法就是在测试代码运行前记录一个起始时间,再测试代码运行完毕后再用当前时间减去起始时间,就得到了测试代码的运行时间。

    即:代码运行时间 = 运行后的时间 - 运行前的时间

    于是可以有下面的代码:

    auto now = std::chrono::system_clock::now();
    test();
    auto dur = std::chrono::system_clock::now() - now;
    

    这段代码简单易懂,缺点是写起来比较麻烦,每次要衡量一段代码的执行时间时,都需要在开头和结尾写上相应的代码。

    可以通过撰写一个通用的测试函数解决这一问题:

    auto test_func_duration = [](auto &&func, auto &&...params)
    {
    	auto now = std::chrono::system_clock::now();
    	std::forward<decltype(func)>(func)(
    		std::forward<decltype(params)>(params)...
    		);
    	auto dur = std::chrono::system_clock::now() - now;
    
    	std::cout << "duration ms: " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    };
    

    该函数略微有些复杂,auto&& 这里是万能引用的意思,故而传递到下层函数调用前需要使用 std::forward 来保持其原始类型。

    不过,上述方法仍然没那么灵活,它必须传递一个函数进行测试,而不能测试一段复杂的代码。

    可以采用下面的(第三种方法)一个比较理想的工具:

    class Benchmark
    {
    public:
    	Benchmark()
    	{
    		m_begin = std::chrono::system_clock::now();
    	}
    	~Benchmark()
    	{
    		auto dur = std::chrono::system_clock::now() - m_begin;
    		std::cout << "duration ms: " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    	}
    	Benchmark(const Benchmark &) = delete;
    	Benchmark &operator=(const Benchmark &) = delete;
    
    private:
    	using time_point = decltype(std::chrono::system_clock::now());
    	time_point m_begin;
    };
    

    该类型的实例可以在代码块的开始创建,然后它就可以采用RAII来衡量之后到其销毁时间段内的执行时间。

    由于采取的是class,因此很容易做更多的扩展,也就是附加一些额外的信息。通常是用来调整输出内容的信息。

    具体的测试代码见:

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <set>
    
    std::set<int> test_set;
    void test()
    {
    	for (int i = 0; i < 1000000; ++i)
    	{
    		test_set.insert(i);
    	}
    }
    
    auto test_func_duration = [](auto &&func, auto &&...params)
    {
    	auto now = std::chrono::system_clock::now();
    	std::forward<decltype(func)>(func)(
    		std::forward<decltype(params)>(params)...
    		);
    	auto dur = std::chrono::system_clock::now() - now;
    
    	std::cout << "duration ms: " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    };
    
    class Benchmark
    {
    public:
    	Benchmark()
    	{
    		m_begin = std::chrono::system_clock::now();
    	}
    	~Benchmark()
    	{
    		auto dur = std::chrono::system_clock::now() - m_begin;
    		std::cout << "duration ms: " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    	}
    	Benchmark(const Benchmark &) = delete;
    	Benchmark &operator=(const Benchmark &) = delete;
    
    private:
    	using time_point = decltype(std::chrono::system_clock::now());
    	time_point m_begin;
    };
    
    int main()
    {
    	// 方法1
    	// auto now = std::chrono::system_clock::now();
    	// test();
    	// auto dur = std::chrono::system_clock::now() - now;
    
    	// std::cout << "duration ms: " << std::chrono::duration_cast<std::chrono::milliseconds>(dur).count() << std::endl;
    
    	// 方法2
    	//test_func_duration(test);
    
    	// 方法3
    	{
    		Benchmark bm;
    		test();
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    vscode常用插件列表
    使用docker构建supervisor全步骤
    docker删除虚悬镜像(临时镜像文件)
    消息队列的对比
    ECharts使用:this.dom.getContext is not a function
    curl命令行请求
    工作工具清单
    《SQL优化入门》讲座总结
    初始化git库并配置自动部署
    php代码进行跨域请求处理
  • 原文地址:https://www.cnblogs.com/demon90s/p/15579741.html
Copyright © 2011-2022 走看看