函数运行计时器Timer

背景介绍

  最近在补充和复习C++并发编程的相关知识。为了能够直观有效地评估并发和非并发函数的执行时间差异,编写一个计时器Timer类能够统计输出函数的执行时间。

代码实现

  Timer类只提供一个公有的模板方法measureExecutionTime,模板参数中可以指定输出的时间单位(默认为毫秒),函数参数为无参的函数对象。该方法中,通过在传入的函数对象调用前后添加时间戳的方法统计并输出执行用时。代码实现如下:

#include <iostream>
#include <chrono>
#include <functional>

class Timer{
public:
    template<typename TimePrecision = std::chrono::milliseconds>
    void measureExecutionTime(std::function<void()> func){
        start();
        func(); // 执行可执行对象
        stop();
        displayElapsedTime<TimePrecision>();
    }

private:
    std::chrono::high_resolution_clock::time_point m_startTime;
    std::chrono::high_resolution_clock::time_point m_endTime;

    void start(){
        m_startTime = std::chrono::high_resolution_clock::now();
    }

    void stop(){
        m_endTime = std::chrono::high_resolution_clock::now();
    }

    template<typename TimePrecision>
    TimePrecision getElapsedTime(){
        return std::chrono::duration_cast<TimePrecision>(m_endTime - m_startTime);
    }

    template<typename TimePrecision>
    void displayElapsedTime(){
        std::string units;
        if constexpr (std::is_same_v<TimePrecision, std::chrono::nanoseconds>) {
            units = "nanoseconds";
        } else if constexpr (std::is_same_v<TimePrecision, std::chrono::microseconds>) {
            units = "microseconds";
        } else if constexpr (std::is_same_v<TimePrecision, std::chrono::milliseconds>) {
            units = "milliseconds";
        } else if constexpr (std::is_same_v<TimePrecision, std::chrono::seconds>) {
            units = "seconds";
        } else {
            units = "unknown units";
        }
        std::cout << "Elapsed time: " << getElapsedTime<TimePrecision>().count() << " " << units << std::endl;
    }
};

使用方法

  考虑到Timer类并不应该对外部执行函数有任何感知,所以Timer类公有接口的参数为无参的函数对象。故而,如果需要执行的函数有参数,那么将其封成一个lambda表达式传入即可。如下为该类的使用示例:

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>

#include "timer.h"
// 定义一个简单的函数
void myFunction() {
    std::cout << "Executing myFunction..." << std::endl;
    // 模拟一些耗时操作
    std::this_thread::sleep_for(std::chrono::seconds(2));
}

int main() {
    Timer timer;

    // 使用函数
    timer.measureExecutionTime(myFunction);

    // 使用 lambda 表达式
    timer.measureExecutionTime<std::chrono::microseconds>([]() {
        std::cout << "Executing lambda..." << std::endl;
        // 模拟一些耗时操作
        std::this_thread::sleep_for(std::chrono::seconds(1));
    });

    return 0;
}

  上述使用示例的运行结果如下:

Executing myFunction...
Elapsed time: 2015 milliseconds
Executing lambda...
Elapsed time: 1001076 microseconds 

当珍惜每一片时光~