C++11使用chrono获取当前时间戳

在 C++ 中,获取当前时间戳最推荐的方式是使用 C++11 引入的 <chrono> 库,它提供了高精度、类型安全的时间操作。根据需求,可以获取不同精度的时间戳(如秒、毫秒、微秒、纳秒)。

下面是几种常见场景的示例代码:

1. 获取秒级时间戳(自 1970-01-01 以来的秒数)

cpp

复制代码
#include <iostream>
#include <chrono>

int main() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();
    // 转换为 time_t 类型(秒精度)
    std::time_t timestamp = std::chrono::system_clock::to_time_t(now);
    std::cout << "秒级时间戳: " << timestamp << std::endl;
    return 0;
}

2. 获取毫秒级时间戳

cpp

复制代码
#include <iostream>
#include <chrono>

int main() {
    auto now = std::chrono::system_clock::now();
    // 从纪元到现在的毫秒数
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
        now.time_since_epoch()
    );
    std::cout << "毫秒级时间戳: " << ms.count() << std::endl;
    return 0;
}

3. 获取微秒级时间戳

cpp

复制代码
#include <iostream>
#include <chrono>

int main() {
    auto now = std::chrono::system_clock::now();
    auto us = std::chrono::duration_cast<std::chrono::microseconds>(
        now.time_since_epoch()
    );
    std::cout << "微秒级时间戳: " << us.count() << std::endl;
    return 0;
}

4. 获取纳秒级时间戳(如果系统时钟支持)

cpp

复制代码
#include <iostream>
#include <chrono>

int main() {
    auto now = std::chrono::system_clock::now();
    auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
        now.time_since_epoch()
    );
    std::cout << "纳秒级时间戳: " << ns.count() << std::endl;
    return 0;
}

5. 使用 std::time 的简化方式(秒精度,C 风格)

cpp

复制代码
#include <iostream>
#include <ctime>

int main() {
    std::time_t timestamp = std::time(nullptr);
    std::cout << "秒级时间戳: " << timestamp << std::endl;
    return 0;
}

注意事项:

  • std::chrono::system_clock 的时间点通常表示 UTC 时间,其纪元(epoch)是 1970-01-01 00:00:00 UTC。

  • duration_cast 用于转换不同精度,如果需要浮点数秒(例如 1.234 秒),可以使用 duration<double>

  • C++20 引入了更便捷的 std::chrono::clock_cast 和日历扩展,但上述代码在 C++11 及以上均可编译。

如果想统计时间差(如某个函数执行时长),可用以下方法。

6. 基础用法:测量单次调用耗时(微秒/纳秒)

cpp

复制代码
#include <iostream>
#include <chrono>

// 示例函数:模拟耗时操作
void someFunction() {
    // 模拟工作负载
    for (volatile int i = 0; i < 1000000; ++i) {}
}

int main() {
    auto start = std::chrono::high_resolution_clock::now();

    someFunction();  // 要测量的函数

    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

    std::cout << "函数耗时: " << duration.count() << " 微秒" << std::endl;
    return 0;
}

7. 使用宏或模板简化测量(自动打印耗时)

cpp

复制代码
#include <iostream>
#include <chrono>

#define MEASURE_TIME(func) do { \
    auto start = std::chrono::high_resolution_clock::now(); \
    func; \
    auto end = std::chrono::high_resolution_clock::now(); \
    auto dur = std::chrono::duration_cast<std::chrono::microseconds>(end - start); \
    std::cout << #func << " 耗时: " << dur.count() << " us" << std::endl; \
} while(0)

void myTask() {
    for (volatile int i = 0; i < 500000; ++i) {}
}

int main() {
    MEASURE_TIME(myTask());
    return 0;
}

8. 封装成通用计时器类(支持多次测量与平均值)

cpp

复制代码
#include <iostream>
#include <chrono>
#include <vector>

class Timer {
public:
    void start() {
        _start = std::chrono::high_resolution_clock::now();
    }

    void stop() {
        _end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(_end - _start);
        _records.push_back(duration.count());
    }

    double getAverageMicroseconds() const {
        if (_records.empty()) return 0.0;
        double sum = 0.0;
        for (auto t : _records) sum += t;
        return sum / _records.size();
    }

    void clear() {
        _records.clear();
    }

private:
    std::chrono::time_point<std::chrono::high_resolution_clock> _start, _end;
    std::vector<long long> _records;
};

// 示例函数
int compute(int n) {
    int sum = 0;
    for (volatile int i = 0; i < n; ++i) sum += i;
    return sum;
}

int main() {
    Timer timer;
    const int iterations = 10;
    for (int i = 0; i < iterations; ++i) {
        timer.start();
        compute(1000000);
        timer.stop();
    }
    std::cout << "平均耗时: " << timer.getAverageMicroseconds() << " 微秒" << std::endl;
    return 0;
}

9. 注意编译器优化的影响

如果被测函数内部没有明显的副作用,编译器可能会将整个函数优化掉,导致测量结果接近 0。解决方法:

  • 使用 volatile 变量(如上例所示)。

  • 将计算结果输出或赋值给 volatile 变量。

  • 使用 #pragma optimize 关闭局部优化(不推荐)。

  • 使用基准测试框架(如 Google Benchmark)。

反例(可能被优化掉):

cpp

复制代码
void emptyLoop() {
    for (int i = 0; i < 1000000; ++i) {}  // 空循环可能被优化删除
}

修正:

cpp

复制代码
void notEmptyLoop() {
    volatile int sum = 0;
    for (int i = 0; i < 1000000; ++i) sum += i;
}

10. 高精度与不同精度的选择

  • std::chrono::high_resolution_clock:最高精度的时钟(通常是纳秒级)。

  • std::chrono::steady_clock:单调时钟,不受系统时间调整影响,适合测量间隔。

  • std::chrono::system_clock:系统实时时钟,可能被调整,不适合测量耗时。

推荐 :测量耗时优先使用 steady_clockhigh_resolution_clock(通常后者是前者的别名)。

cpp

复制代码
auto start = std::chrono::steady_clock::now();
// ... function ...
auto end = std::chrono::steady_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);

完整可运行示例(包含纳秒输出)

cpp

复制代码
#include <iostream>
#include <chrono>

void heavyWork() {
    volatile long long sum = 0;
    for (int i = 0; i < 1000000; ++i) {
        sum += i;
    }
}

int main() {
    auto start = std::chrono::steady_clock::now();
    heavyWork();
    auto end = std::chrono::steady_clock::now();

    auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
    auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

    std::cout << "耗时: " << ns.count() << " ns\n";
    std::cout << "耗时: " << us.count() << " us\n";
    std::cout << "耗时: " << ms.count() << " ms\n";
    return 0;
}

总结

  • 使用 <chrono>steady_clock + duration_cast

  • 注意防止编译器优化。

  • 多次测量取平均更可靠。

  • 对于复杂的性能分析,建议使用专门的 Profiler(如 perf, VTune)或 Google Benchmark 库。

如果需要测量一个函数在真实环境中的耗时(包含 I/O、锁竞争等),可以保持函数原样测量;如果只测量算法 CPU 时间,需排除其他干扰,可以多次调用取最小值或使用 std::chrono::steady_clock 配合高优先级线程。

相关推荐
Shadow(⊙o⊙)1 小时前
硬核手搓解析!进程-内核分析:命令行参数及环境变量,重构main()
linux·运维·服务器·开发语言·c++·后端·学习
YYYing.1 小时前
【C++项目之高并发内存池 (五)】一些小细节和性能优化及整体测试
c++·性能优化·高并发·内存池·基数树
2301_789015621 小时前
Linux:基础指令(二)
linux·运维·服务器·c语言·开发语言·c++·算法
闻缺陷则喜何志丹1 小时前
【区间合并】P7912 [CSP-J 2021] 小熊的果篮|普及+
c++·算法·洛谷·区间合并
REDcker10 小时前
C++变量存储与ELF段布局详解 从const全局到rodata与nm_readelf验证实践
java·c++·面试
王老师青少年编程13 小时前
csp信奥赛C++高频考点专项训练之字符串 --【字符串排序】:合并序列
c++·字符串·csp·高频考点·信奥赛·字符串排序·合并序列
handler0113 小时前
UDP协议与网络通信知识点
c语言·网络·c++·笔记·网络协议·udp
神仙别闹14 小时前
基于QT(C++)实现学生成绩管理系统
数据库·c++·qt
君义_noip15 小时前
CSP-S 2025 入门级 第一轮(初赛) 完善程序(1)
c++·算法·信息学奥赛·初赛·csp 第一轮