在 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_clock 或 high_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 配合高优先级线程。