一、Windows 专用
以下实现高精度(支持微秒/纳秒)、带 ID 管理、可同时测多个计时器的 C++ 类。
- 开始计时
- 结束计时
- 按 ID 区分多个计时器
- 获取时间(微秒 / 纳秒)
- 按 ID 顺序打印所有已测时间
- Windows 高精度
QueryPerformanceCounter
代码块
cpp
#include <Windows.h>
#include <iostream>
#include <vector>
#include <unordered_map>
class HighResolutionTimer
{
private:
// 单个计时器的数据结构
struct TimerData
{
LARGE_INTEGER start;
LARGE_INTEGER end;
bool isRunning = false;
bool hasFinished = false;
};
LARGE_INTEGER m_freq; // 系统时钟频率
std::unordered_map<int, TimerData> m_timers; // 按 ID 存储计时器
std::vector<int> m_idOrder; // 记录 ID 顺序(保证打印顺序)
public:
// 构造函数:初始化高精度时钟
HighResolutionTimer()
{
QueryPerformanceFrequency(&m_freq);
}
// ====================== 开始计时(指定ID) ======================
void start(int id)
{
// 如果是新ID,记录顺序
if (m_timers.find(id) == m_timers.end())
{
m_idOrder.push_back(id);
}
auto& timer = m_timers[id];
QueryPerformanceCounter(&timer.start);
timer.isRunning = true;
timer.hasFinished = false;
}
// ====================== 结束计时(指定ID) ======================
void stop(int id)
{
if (m_timers.find(id) == m_timers.end())
{
std::cerr << "ID " << id << " 未开始计时!" << std::endl;
return;
}
auto& timer = m_timers[id];
if (!timer.isRunning)
{
std::cerr << "ID " << id << " 未在运行中!" << std::endl;
return;
}
QueryPerformanceCounter(&timer.end);
timer.isRunning = false;
timer.hasFinished = true;
}
// ====================== 获取时间:微秒 us ======================
long long getElapsedMicroseconds(int id)
{
if (!isValid(id)) return -1;
auto& t = m_timers[id];
return (t.end.QuadPart - t.start.QuadPart) * 1000000LL / m_freq.QuadPart;
}
// ====================== 获取时间:纳秒 ns ======================
long long getElapsedNanoseconds(int id)
{
if (!isValid(id)) return -1;
auto& t = m_timers[id];
return (t.end.QuadPart - t.start.QuadPart) * 1000000000LL / m_freq.QuadPart;
}
// ====================== 按ID顺序打印所有结果 ======================
void printAll()
{
std::cout << "\n======= 所有计时器结果(按ID顺序)=======\n";
for (int id : m_idOrder)
{
if (!m_timers[id].hasFinished)
{
std::cout << "ID " << id << ":未完成\n";
continue;
}
auto us = getElapsedMicroseconds(id);
auto ns = getElapsedNanoseconds(id);
std::cout << "ID " << id
<< " | 耗时: " << us << " us (" << ns << " ns)\n";
}
std::cout << "=========================================\n\n";
}
// 清空所有计时器
void clear()
{
m_timers.clear();
m_idOrder.clear();
}
private:
bool isValid(int id)
{
if (m_timers.find(id) == m_timers.end())
{
std::cerr << "ID " << id << " 不存在!" << std::endl;
return false;
}
if (!m_timers[id].hasFinished)
{
std::cerr << "ID " << id << " 未停止!" << std::endl;
return false;
}
return true;
}
};
使用示例
cpp
int main()
{
HighResolutionTimer timer;
// 同时测多个任务
timer.start(1);
// 你的代码...
timer.stop(1);
timer.start(2);
// 你的代码...
timer.stop(2);
timer.start(10);
// 你的代码...
timer.stop(10);
// 获取单个时间
auto us = timer.getElapsedMicroseconds(1);
auto ns = timer.getElapsedNanoseconds(1);
// 一键打印所有(按你 start 的顺序)
timer.printAll();
return 0;
}
输出效果
======= 所有计时器结果(按ID顺序)=======
ID 1 | 耗时: 12 us (12543 ns)
ID 2 | 耗时: 84 us (84120 ns)
ID 10 | 耗时: 421 us (421340 ns)
=========================================
二、多平台通用
以下为跨平台(Windows + Linux + macOS)、线程安全、高精度计时、自动保存日志、支持多ID管理的 C++ 计时器类。
- 多线程安全
- 支持多 ID 同时计时
- start(id) / stop(id)
- getUs(id) / getNs(id)
- printAll() 按顺序打印
- 自动写日志文件(timer_log.txt)
- 跨平台兼容(Windows/Linux/macOS)
- 微秒、纳秒精度
- 无第三方依赖,C++11 及以上即可
代码块
cpp
#include <iostream>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <fstream>
#include <chrono>
#include <string>
#ifdef _WIN32
#include <windows.h>
#endif
using namespace std;
using namespace chrono;
class HighResolutionTimer
{
private:
struct TimerRecord
{
time_point<high_resolution_clock> start;
time_point<high_resolution_clock> end;
bool running = false;
bool finished = false;
};
unordered_map<int, TimerRecord> m_records;
vector<int> m_id_order;
mutex m_mutex; // 线程安全
ofstream m_log_file; // 日志文件
public:
HighResolutionTimer()
{
// 自动打开日志
m_log_file.open("timer_log.txt", ios::out | ios::app);
}
~HighResolutionTimer()
{
if (m_log_file.is_open())
m_log_file.close();
}
// ===================== 开始计时 =====================
void start(int id)
{
lock_guard<mutex> lock(m_mutex);
if (m_records.find(id) == m_records.end())
m_id_order.push_back(id);
auto& rec = m_records[id];
rec.start = high_resolution_clock::now();
rec.running = true;
rec.finished = false;
}
// ===================== 停止计时 =====================
void stop(int id)
{
lock_guard<mutex> lock(m_mutex);
if (m_records.find(id) == m_records.end())
return;
auto& rec = m_records[id];
if (!rec.running)
return;
rec.end = high_resolution_clock::now();
rec.running = false;
rec.finished = true;
// 自动写入日志
writeLog(id);
}
// ===================== 获取微秒 =====================
long long getUs(int id)
{
lock_guard<mutex> lock(m_mutex);
if (!valid(id)) return -1;
auto& r = m_records[id];
return duration_cast<microseconds>(r.end - r.start).count();
}
// ===================== 获取纳秒 =====================
long long getNs(int id)
{
lock_guard<mutex> lock(m_mutex);
if (!valid(id)) return -1;
auto& r = m_records[id];
return duration_cast<nanoseconds>(r.end - r.start).count();
}
// ===================== 打印所有(按ID顺序) =====================
void printAll()
{
lock_guard<mutex> lock(m_mutex);
cout << "\n======= 计时器结果(按启动顺序) =======\n";
for (int id : m_id_order)
{
auto& r = m_records[id];
if (!r.finished)
{
cout << "ID " << id << ":未完成\n";
continue;
}
long long us = getUs(id);
long long ns = getNs(id);
cout << "ID " << id
<< " | " << us << " us (" << ns << " ns)\n";
}
cout << "========================================\n\n";
}
// 清空所有记录
void clear()
{
lock_guard<mutex> lock(m_mutex);
m_records.clear();
m_id_order.clear();
}
private:
bool valid(int id)
{
if (m_records.find(id) == m_records.end()) return false;
if (!m_records[id].finished) return false;
return true;
}
// ===================== 自动写日志 =====================
void writeLog(int id)
{
if (!m_log_file.is_open()) return;
auto& r = m_records[id];
long long us = duration_cast<microseconds>(r.end - r.start).count();
long long ns = duration_cast<nanoseconds>(r.end - r.start).count();
m_log_file << "[TIMER] ID=" << id
<< " | time=" << us << " us (" << ns << " ns)\n";
m_log_file.flush();
}
};
使用示例
cpp
#include <thread>
void testTask(HighResolutionTimer& timer, int id)
{
timer.start(id);
// 模拟你的代码运行
for (int i = 0; i < 1000000; i++);
timer.stop(id);
}
int main()
{
HighResolutionTimer timer;
timer.start(1);
// do something...
timer.stop(1);
timer.start(2);
// do something...
timer.stop(2);
// 多线程测试
thread t1(testTask, ref(timer), 10);
thread t2(testTask, ref(timer), 11);
t1.join();
t2.join();
timer.printAll();
return 0;
}
日志文件示例(自动生成)
[TIMER] ID=1 | time=12 us (12543 ns)
[TIMER] ID=2 | time=84 us (84120 ns)
[TIMER] ID=10 | time=421 us (421340 ns)
三、多平台+名称区分
日志自动按天分文件 + 带时间戳、 不用 int ID,改用 std::string 名称区分定时器类
代码块
cpp
#include <iostream>
#include <vector>
#include <unordered_map>
#include <mutex>
#include <fstream>
#include <chrono>
#include <string>
#include <iomanip>
#include <ctime>
using namespace std;
using namespace chrono;
class HighResolutionTimer
{
private:
struct TimerRecord
{
time_point<high_resolution_clock> start;
time_point<high_resolution_clock> end;
bool running = false;
bool finished = false;
};
unordered_map<string, TimerRecord> m_records;
vector<string> m_name_order; // 按名称创建顺序保存
mutex m_mutex;
ofstream m_log_file;
string m_current_date;
public:
HighResolutionTimer() {
updateLogFile();
}
~HighResolutionTimer() {
if (m_log_file.is_open())
m_log_file.close();
}
// ===================== 开始计时(string 名称) =====================
void start(const string& name)
{
lock_guard<mutex> lock(m_mutex);
if (m_records.find(name) == m_records.end())
m_name_order.push_back(name);
auto& rec = m_records[name];
rec.start = high_resolution_clock::now();
rec.running = true;
rec.finished = false;
}
// ===================== 停止计时 =====================
void stop(const string& name)
{
lock_guard<mutex> lock(m_mutex);
if (m_records.find(name) == m_records.end())
return;
auto& rec = m_records[name];
if (!rec.running)
return;
rec.end = high_resolution_clock::now();
rec.running = false;
rec.finished = true;
writeLog(name);
}
// ===================== 获取微秒 =====================
long long getUs(const string& name)
{
lock_guard<mutex> lock(m_mutex);
if (!valid(name)) return -1;
auto& r = m_records[name];
return duration_cast<microseconds>(r.end - r.start).count();
}
// ===================== 获取纳秒 =====================
long long getNs(const string& name)
{
lock_guard<mutex> lock(m_mutex);
if (!valid(name)) return -1;
auto& r = m_records[name];
return duration_cast<nanoseconds>(r.end - r.start).count();
}
// ===================== 打印所有(按创建顺序) =====================
void printAll()
{
lock_guard<mutex> lock(m_mutex);
cout << "\n======= 计时器结果 =======\n";
for (auto& name : m_name_order)
{
auto& r = m_records[name];
if (!r.finished) {
cout << name << ":未完成\n";
continue;
}
cout << name << " | "
<< getUs(name) << " us ("
<< getNs(name) << " ns)\n";
}
cout << "==========================\n\n";
}
void clear()
{
lock_guard<mutex> lock(m_mutex);
m_records.clear();
m_name_order.clear();
}
private:
bool valid(const string& name)
{
if (m_records.find(name) == m_records.end()) return false;
if (!m_records[name].finished) return false;
return true;
}
// ===================== 获取当前日期 YYYYMMDD =====================
string getCurrentDate()
{
auto now = time(nullptr);
tm tm_time{};
#ifdef _WIN32
localtime_s(&tm_time, &now);
#else
localtime_r(&now, &tm_time);
#endif
ostringstream oss;
oss << put_time(&tm_time, "%Y%m%d");
return oss.str();
}
// ===================== 获取时间戳 YYYY-MM-DD HH:MM:SS =====================
string getTimestamp()
{
auto now = time(nullptr);
tm tm_time{};
#ifdef _WIN32
localtime_s(&tm_time, &now);
#else
localtime_r(&now, &tm_time);
#endif
ostringstream oss;
oss << put_time(&tm_time, "%Y-%m-%d %H:%M:%S");
return oss.str();
}
// ===================== 自动切换日期文件 =====================
void updateLogFile()
{
string today = getCurrentDate();
if (today == m_current_date && m_log_file.is_open())
return;
if (m_log_file.is_open())
m_log_file.close();
m_current_date = today;
string filename = "timer_" + today + ".log";
m_log_file.open(filename, ios::app | ios::out);
m_log_file << "=====================================\n";
m_log_file << "日志开始:" << getTimestamp() << "\n";
m_log_file << "=====================================\n\n";
}
// ===================== 写日志(带时间戳 + 自动切分文件) =====================
void writeLog(const string& name)
{
lock_guard<mutex> lock(m_mutex);
updateLogFile();
auto& r = m_records[name];
long long us = duration_cast<microseconds>(r.end - r.start).count();
long long ns = duration_cast<nanoseconds>(r.end - r.start).count();
m_log_file << "[" << getTimestamp() << "] "
<< "NAME: " << setw(20) << left << name
<< " | " << us << " us (" << ns << " ns)\n";
m_log_file.flush();
}
};
使用示例
cpp
#include <thread>
void testFunc(HighResolutionTimer& timer, const string& name)
{
timer.start(name);
// 你的业务代码
for (int i = 0; i < 1000000; i++);
timer.stop(name);
}
int main()
{
HighResolutionTimer timer;
timer.start("数据加载");
// ...
timer.stop("数据加载");
timer.start("图像处理");
// ...
timer.stop("图像处理");
// 多线程也安全
thread t1(testFunc, ref(timer), "网络请求");
thread t2(testFunc, ref(timer), "算法计算");
t1.join();
t2.join();
timer.printAll();
return 0;
}
日志效果
文件名:timer_20260407.log
[2026-04-07 22:10:05] NAME: 数据加载 | 12 us (12543 ns)
[2026-04-07 22:10:05] NAME: 图像处理 | 84 us (84120 ns)
[2026-04-07 22:10:05] NAME: 网络请求 | 421 us (421340 ns)