You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++代码块墙钟时间聚合:手动统计循环内代码段总耗时

在C++中实现循环内代码段的累计计时

我来帮你把这个Python风格的计时逻辑转换成跨平台的C++实现,完全基于标准库,不用依赖任何第三方工具或者系统特定API~

核心思路:用C++标准库的<chrono>模块

C++11及以后的标准库提供了<chrono>头文件,专门用于处理时间相关操作,其中的high_resolution_clock是精度最高的时钟,非常适合做性能计时。我们的思路和你的Python伪代码完全对应:

  • 初始化累计时间变量(用足够大的类型避免溢出)
  • 循环内每次执行目标代码前记录开始时间
  • 代码执行完成后计算耗时,累加到总时间里
  • 最后把累计时间转换成易读的单位输出

完整代码示例

下面是直接对应你需求的实现,我加了模拟业务函数的代码,你可以直接替换成自己的逻辑:

#include <iostream>
#include <chrono>
#include <vector>
#include <thread> // 仅用于模拟耗时,实际业务代码不需要

// 模拟你的step1业务逻辑
void run_step_1(const std::pair<int, int>& pair) {
    // 这里替换成你的实际代码
    std::this_thread::sleep_for(std::chrono::microseconds(10)); // 模拟10微秒耗时
}

// 模拟你的step2业务逻辑
void run_step_2(const std::pair<int, int>& pair) {
    // 这里替换成你的实际代码
    std::this_thread::sleep_for(std::chrono::microseconds(20)); // 模拟20微秒耗时
}

int main() {
    // 用long long存储累计时间,避免多次累加后溢出,单位是微秒
    long long total_step1 = 0;
    long long total_step2 = 0;

    // 模拟你的pairs集合,替换成你实际的数据源
    std::vector<std::pair<int, int>> pairs = {{1,2}, {3,4}, {5,6}, {7,8}, {9,10}};

    for (const auto& pair : pairs) {
        // 计时step1
        const auto start_step1 = std::chrono::high_resolution_clock::now();
        run_step_1(pair);
        const auto end_step1 = std::chrono::high_resolution_clock::now();
        // 计算耗时并累加,转换成微秒
        total_step1 += std::chrono::duration_cast<std::chrono::microseconds>(end_step1 - start_step1).count();

        // 计时step2
        const auto start_step2 = std::chrono::high_resolution_clock::now();
        run_step_2(pair);
        const auto end_step2 = std::chrono::high_resolution_clock::now();
        total_step2 += std::chrono::duration_cast<std::chrono::microseconds>(end_step2 - start_step2).count();
    }

    // 输出结果,转换成更易读的单位(毫秒/秒)
    std::cout << "Total time for step 1: " << total_step1 / 1000.0 << " ms" << std::endl;
    std::cout << "Total time for step 2: " << total_step2 / 1000.0 << " ms" << std::endl;
    std::cout << "Total combined time: " << (total_step1 + total_step2) / 1000000.0 << " s" << std::endl;

    return 0;
}

关键细节说明

  • 时钟选择std::chrono::high_resolution_clock是C++提供的精度最高的时钟,不同平台可能对应不同的底层实现(比如Linux上的CLOCK_MONOTONIC_RAW),但都是系统能提供的最高精度;
  • 时间单位转换duration_cast用来把时间差转换成具体的单位(微秒、毫秒、纳秒等),count()方法获取对应的数值;
  • 避免溢出:用long long存储累计时间,因为如果循环次数很多,用int很容易溢出;如果需要更高精度,可以用纳秒,但要注意系统是否支持;
  • 跨平台性:完全基于C++标准库,在Windows、Linux、macOS上都能正常运行。

进阶优化:封装计时器类

如果你的代码中有很多需要计时的地方,建议封装一个简单的计时器类,让代码更整洁:

#include <iostream>
#include <chrono>
#include <vector>
#include <thread>

class Timer {
private:
    using Clock = std::chrono::high_resolution_clock;
    std::chrono::microseconds total_time = std::chrono::microseconds(0);
    std::chrono::time_point<Clock> start_point;

public:
    // 开始计时
    void start() {
        start_point = Clock::now();
    }

    // 结束计时并累加时间
    void stop() {
        const auto end_point = Clock::now();
        total_time += std::chrono::duration_cast<std::chrono::microseconds>(end_point - start_point);
    }

    // 获取累计时间(微秒)
    long long get_total_us() const {
        return total_time.count();
    }

    // 获取累计时间(毫秒)
    double get_total_ms() const {
        return get_total_us() / 1000.0;
    }

    // 获取累计时间(秒)
    double get_total_s() const {
        return get_total_us() / 1000000.0;
    }
};

void run_step_1(const std::pair<int, int>& pair) {
    std::this_thread::sleep_for(std::chrono::microseconds(10));
}

void run_step_2(const std::pair<int, int>& pair) {
    std::this_thread::sleep_for(std::chrono::microseconds(20));
}

int main() {
    Timer timer_step1, timer_step2;
    std::vector<std::pair<int, int>> pairs = {{1,2}, {3,4}, {5,6}};

    for (const auto& pair : pairs) {
        timer_step1.start();
        run_step_1(pair);
        timer_step1.stop();

        timer_step2.start();
        run_step_2(pair);
        timer_step2.stop();
    }

    std::cout << "Step 1 total time: " << timer_step1.get_total_ms() << " ms" << std::endl;
    std::cout << "Step 2 total time: " << timer_step2.get_total_ms() << " ms" << std::endl;

    return 0;
}

这样每次计时只需要调用start()stop(),代码更简洁,也不容易出错。

内容的提问来源于stack exchange,提问作者Andrea Zonca

火山引擎 最新活动