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

如何利用std::chrono实现<1秒的精确计时及多单位精准展示?

问题描述

想要计算程序中算法的运行时间,并以小时、分钟、秒、毫秒等不同单位展示,现有实现如下:

auto start = high_resolution_clock::now();
myFunction();
auto stop = high_resolution_clock::now();
auto duration = duration_cast<seconds>(stop - start);

const auto hrs = duration_cast<hours>(duration);
const auto mins = duration_cast<minutes>(duration - hrs);
const auto secs = duration_cast<seconds>(duration - hrs - mins);
const auto ms = duration_cast<milliseconds>(duration - hrs - mins - secs);
std::cout << "Time needed: "<<hrs.count()<<" hours "<<mins.count()<<" mins "<<secs.count()<<" secs " <<ms.count()<<" milisecs "

期望输出示例:

Time needed: 0 hours 1 mins 30 seconds 2400miliseconds

但实际运行存在问题:

  • 运行时间<1秒时,所有值(包括毫秒)都显示为0;
  • 运行时间≥1秒时,无法显示精确时间,比如实际非整1秒,却输出:
Time needed: 0 hours 0 mins 1 seconds 1000miliseconds

该实现因先将时间差转换为整秒,丢失了高精度信息,导致无法体现真实运行时间,需要解决此问题,同时希望了解除std::chrono之外的其他可行方法。

解决方法

一、修正std::chrono的实现

问题核心是过早将时间差转换为秒级,丢失了毫秒及以下的精度。正确的做法是保留原始的高精度时间差,再依次转换为不同单位:

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

void myFunction() {
    // 示例函数,模拟耗时操作
    std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}

int main() {
    auto start = std::chrono::high_resolution_clock::now();
    myFunction();
    auto stop = std::chrono::high_resolution_clock::now();
    
    // 保留原始高精度时间差,不提前转换为秒
    auto duration = stop - start;

    // 从大到小依次计算各单位的时间,每次减去已计算的部分
    const auto hrs = std::chrono::duration_cast<std::chrono::hours>(duration);
    duration -= hrs;
    const auto mins = std::chrono::duration_cast<std::chrono::minutes>(duration);
    duration -= mins;
    const auto secs = std::chrono::duration_cast<std::chrono::seconds>(duration);
    duration -= secs;
    const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration);

    std::cout << "Time needed: " << hrs.count() << " hours " 
              << mins.count() << " mins " 
              << secs.count() << " seconds " 
              << ms.count() << " milliseconds\n";
    return 0;
}

这段代码会输出类似:Time needed: 0 hours 0 mins 1 seconds 500 milliseconds,完全保留了时间精度。如果需要显示微秒或纳秒,只需要继续添加对应的转换步骤即可:

duration -= ms;
const auto us = std::chrono::duration_cast<std::chrono::microseconds>(duration);
// 输出时加上us.count() << " microseconds"

二、其他可行方法

1. C标准库的clock()函数

适用于测量CPU时间(进程占用的CPU时间,而非实际流逝时间),单位为时钟周期,需要转换为秒:

#include <time.h>
#include <iostream>
#include <thread>

void myFunction() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}

int main() {
    clock_t start = clock();
    myFunction();
    clock_t end = clock();
    
    double cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
    // 转换为毫秒、微秒
    long ms = (long)(cpu_time_used * 1000);
    long us = (long)(cpu_time_used * 1000000);
    
    std::cout << "CPU time used: " << cpu_time_used << " seconds (" 
              << ms << " ms, " << us << " us)\n";
    return 0;
}

注意:clock()测量的是CPU时间,如果程序处于休眠状态,这部分时间不会被计入。

2. Linux/Unix下的gettimeofday()

可以获取当前的墙上时间(实际流逝时间),精度到微秒:

#include <sys/time.h>
#include <iostream>
#include <thread>

void myFunction() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}

int main() {
    struct timeval start, end;
    gettimeofday(&start, nullptr);
    myFunction();
    gettimeofday(&end, nullptr);
    
    long seconds = end.tv_sec - start.tv_sec;
    long microseconds = end.tv_usec - start.tv_usec;
    if (microseconds < 0) {
        seconds--;
        microseconds += 1000000;
    }
    long ms = seconds * 1000 + microseconds / 1000;
    
    std::cout << "Time needed: " << seconds << " seconds " 
              << ms % 1000 << " milliseconds " 
              << microseconds % 1000 << " microseconds\n";
    return 0;
}

3. Windows下的QueryPerformanceCounter()

这是Windows平台的高精度计时API,精度可达纳秒级:

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

void myFunction() {
    Sleep(1500);
}

int main() {
    LARGE_INTEGER start, end, freq;
    QueryPerformanceFrequency(&freq); // 获取计数器频率
    QueryPerformanceCounter(&start);
    myFunction();
    QueryPerformanceCounter(&end);
    
    // 计算耗时,转换为秒、毫秒、微秒
    double elapsed = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart;
    long seconds = (long)elapsed;
    long ms = (long)(elapsed * 1000) % 1000;
    long us = (long)(elapsed * 1000000) % 1000;
    
    std::cout << "Time needed: " << seconds << " seconds " 
              << ms << " milliseconds " 
              << us << " microseconds\n";
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:45:12