You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

boost::timer::cpu_timer的C++标准库等效方案是什么?

替代boost::timer::cpu_timer的C++标准库方案

好问题!确实,C标准库在很长一段时间里没有像boost::timer::cpu_timer那样能一站式获取墙钟、用户态、内核态时间的工具,但咱们有两种靠谱的解决方案——如果能升级到C20,直接用标准库就能搞定;要是还在用旧标准,也能通过平台相关API组合实现,最终输出格式和你要的完全一致。

C++20 标准原生方案

C++20引入了std::chrono::process_cpu_clock,这是专门为追踪进程CPU时间设计的时钟,它可以同时记录用户态CPU时间和内核态CPU时间。而墙钟时间(wall time)我们可以用std::chrono::steady_clock(它不受系统时间调整影响,比system_clock更适合计时场景)。

下面是完整的示例代码,输出格式和你给出的boost示例完全匹配:

#include <chrono>
#include <iostream>
#include <iomanip>

int main() {
    // 记录起始时间点
    const auto wall_start = std::chrono::steady_clock::now();
    const auto cpu_start = std::chrono::process_cpu_clock::now();

    // ----------------------
    // 这里替换成你要计时的代码
    for (volatile int i = 0; i < 100000000; ++i);
    // ----------------------

    // 记录结束时间点
    const auto wall_end = std::chrono::steady_clock::now();
    const auto cpu_end = std::chrono::process_cpu_clock::now();

    // 计算各时间维度的时长(转换为秒,保留6位小数)
    using fsec = std::chrono::duration<double>;
    const fsec wall_duration = wall_end - wall_start;
    const auto user_duration = std::chrono::duration_cast<fsec>(
        std::chrono::process_cpu_clock::to_user(cpu_end - cpu_start)
    );
    const auto system_duration = std::chrono::duration_cast<fsec>(
        std::chrono::process_cpu_clock::to_system(cpu_end - cpu_start)
    );
    const auto total_cpu = user_duration + system_duration;
    const double cpu_percent = (total_cpu.count() / wall_duration.count()) * 100;

    // 格式化输出,和boost风格一致
    std::cout << std::fixed << std::setprecision(6);
    std::cout << wall_duration.count() << "s wall, "
              << user_duration.count() << "s user + "
              << system_duration.count() << "s system = "
              << total_cpu.count() << "s CPU (" << std::setprecision(1) << cpu_percent << "%)" << std::endl;

    return 0;
}

这段代码的核心是process_cpu_clock::to_user和to_system方法,它们能从CPU时间间隔中拆分出用户态和内核态的耗时,完美替代boost的功能。

C++11/17 兼容方案(平台相关)

如果你的项目还不能升级到C++20,也可以通过平台原生API来实现,核心思路是:用std::chrono::steady_clock获取墙钟时间,用平台API获取进程的用户态/内核态CPU时间。

Linux/macOS 平台

可以使用getrusage函数(来自<sys/resource.h>),它能获取当前进程的资源使用统计,包括用户态和内核态时间:

#include <chrono>
#include <iostream>
#include <iomanip>
#include <sys/resource.h>
#include <unistd.h>

int main() {
    const auto wall_start = std::chrono::steady_clock::now();
    struct rusage start_usage;
    getrusage(RUSAGE_SELF, &start_usage);

    // ----------------------
    // 这里替换成你要计时的代码
    for (volatile int i = 0; i < 100000000; ++i);
    // ----------------------

    const auto wall_end = std::chrono::steady_clock::now();
    struct rusage end_usage;
    getrusage(RUSAGE_SELF, &end_usage);

    // 计算墙钟时间
    using fsec = std::chrono::duration<double>;
    const fsec wall_duration = wall_end - wall_start;

    // 计算用户态和内核态时间(rusage的时间单位是微秒)
    const double user_sec = (end_usage.ru_utime.tv_sec - start_usage.ru_utime.tv_sec) +
                            (end_usage.ru_utime.tv_usec - start_usage.ru_utime.tv_usec) / 1e6;
    const double system_sec = (end_usage.ru_stime.tv_sec - start_usage.ru_stime.tv_sec) +
                              (end_usage.ru_stime.tv_usec - start_usage.ru_stime.tv_usec) / 1e6;
    const double total_cpu = user_sec + system_sec;
    const double cpu_percent = (total_cpu / wall_duration.count()) * 100;

    // 格式化输出
    std::cout << std::fixed << std::setprecision(6);
    std::cout << wall_duration.count() << "s wall, "
              << user_sec << "s user + "
              << system_sec << "s system = "
              << total_cpu << "s CPU (" << std::setprecision(1) << cpu_percent << "%)" << std::endl;

    return 0;
}

Windows 平台

使用GetProcessTimes函数(来自<windows.h>),它能获取进程的创建时间、退出时间、内核态时间和用户态时间:

#include <chrono>
#include <iostream>
#include <iomanip>
#include <windows.h>

// 将FILETIME转换为秒数(FILETIME单位是100纳秒)
double filetime_to_sec(FILETIME ft) {
    ULARGE_INTEGER ul;
    ul.LowPart = ft.dwLowDateTime;
    ul.HighPart = ft.dwHighDateTime;
    return static_cast<double>(ul.QuadPart) / 1e7;
}

int main() {
    const auto wall_start = std::chrono::steady_clock::now();
    FILETIME create_time, exit_time, kernel_start, user_start;
    GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_start, &user_start);

    // ----------------------
    // 这里替换成你要计时的代码
    for (volatile int i = 0; i < 100000000; ++i);
    // ----------------------

    const auto wall_end = std::chrono::steady_clock::now();
    FILETIME kernel_end, user_end;
    GetProcessTimes(GetCurrentProcess(), &create_time, &exit_time, &kernel_end, &user_end);

    // 计算墙钟时间
    using fsec = std::chrono::duration<double>;
    const fsec wall_duration = wall_end - wall_start;

    // 计算用户态和内核态时间
    const double user_sec = filetime_to_sec(user_end) - filetime_to_sec(user_start);
    const double system_sec = filetime_to_sec(kernel_end) - filetime_to_sec(kernel_start);
    const double total_cpu = user_sec + system_sec;
    const double cpu_percent = (total_cpu / wall_duration.count()) * 100;

    // 格式化输出
    std::cout << std::fixed << std::setprecision(6);
    std::cout << wall_duration.count() << "s wall, "
              << user_sec << "s user + "
              << system_sec << "s system = "
              << total_cpu << "s CPU (" << std::setprecision(1) << cpu_percent << "%)" << std::endl;

    return 0;
}

总结

  • 如果项目支持C++20,优先使用std::chrono::process_cpu_clock,这是标准、跨平台的解决方案。
  • 旧标准下,根据目标平台选择对应的原生API,同样能实现和boost::timer::cpu_timer完全一致的输出效果。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:21:45