在C++中,编写代码只是第一步,衡量代码的“效率”同样重要。你如何知道你的sort算法比同事写的快?或者你的新功能导致了多少性能下降?你需要一个“秒表”来精确测量代码的执行时间。
在C++(及C语言)中,你有两种主要的“秒表”:
C 风格 “CPU 秒表” (<ctime>/clock()):
- 比喻:这是一个老式的“机械秒表”,它只在你的 CPU **真正在为你的程序“工作”(执行指令)**时才会“嘀嗒”。
- 特点:它测量的是CPU 时间 (CPU Time)。如果你的程序在“等待”(比如
sleep、等待用户输入或等待网络响应),这个秒表会暂停。 - 精度:较低,受限于
CLOCKS_PER_SEC宏。
现代 C++ 风格 “高精度电子秒表” (<chrono>):
- 比喻:这是一个高精度的“电子秒表”,它测量的是墙上时钟 (Wall Clock)走过的时间。
- 特点:它测量的是真实世界流逝的时间。从你按下“开始”到按下“停止”,无论你的程序是在“工作”还是“等待”,它都在计时。
- 精度:极高(通常可以达到纳秒
ns级别)。 - 这是现代C++中(C++11及以后)强烈推荐的方式。
在本教程中,你将学会:
- C 风格
clock():如何使用“CPU 秒表”。 - C++
std::chrono:如何使用“高精度电子秒表”(推荐!)。 - 新手的“头号噩梦”:CPU 时间vs挂钟时间(Wall Time) 的致命区别。
- 实战演练:通过代码对比两种计时器的不同结果。
- “X光透 视”:用调试器“亲眼目睹”时间点(
time_point)对象。
前置知识说明 (100% 自洽):
- 变量 (Variable):理解存储数据的“盒子”,如
double time_taken;。 - 函数 (Function):理解可重复使用的“代码积木”。
#include:如何包含C++标准库(如<iostream>,<ctime>,<chrono>)。cout:C++ 中用于在屏幕上打印信息的“扬声器”。- 类型转换 (Casting):如
double(value),将value转换为double类型。 - 编译 (Compile):C++代码(“食谱”)必须被“编译”(“烘焙”),才能变成电脑可执行的程序(“蛋糕”)。
第一部分:C 风格clock()(“CPU 秒表”)
clock()函数在<ctime>库中。它返回程序启动到当前时刻为止,CPU 花在你程序上的“嘀嗒数”(Clock Ticks)。
核心步骤:
- 包含
<ctime>。 - 在代码开始前,调用
clock_t start = clock();记录“开始嘀嗒数”。 - 在代码结束后,调用
clock_t end = clock();记录“结束嘀嗒数”。 - 计算差值
double(end - start),然后除以CLOCKS_PER_SEC(一个系统常量,表示“每秒多少嘀嗒数”),得到秒数。
clock_example.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
“手把手”终端模拟 (结果因机器和编译优化而异):
1 2 3 4 5 |
|
缺点:精度不高,且无法测量“等待”时间。
第二部分:现代 C++std::chrono(“高精度电子秒表”)
std::chrono库 (C++11) 是现代C++的黄金标准。它提供了高精度时钟和时间单位(纳秒、微秒、毫秒等)。
核心步骤:
- 包含
<chrono>。 - 使用
auto start = std::chrono::high_resolution_clock::now();获取当前挂钟时间点。 - 使用
auto end = std::chrono::high_resolution_clock::now();获取结束时间点。 - 计算差值:
end - start,得到一个duration(时间段) 对象。 - 使用
std::chrono::duration_cast将这个duration对象转换为你想要的单位(如毫秒)。
chrono_example.cpp(推荐用法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
“手把手”终端模拟 (结果因机器而异):
1 2 3 4 5 6 |
|
顿悟时刻:结果1658毫秒,约等于1158毫秒 (CPU工作) +500毫秒 (休眠)。<chrono>正确地测量了所有流逝的时间!
第三部分:新手的“头号噩梦”——clock()vs<chrono>
让我们把两个“秒表”放在同一个程序里,测量同一个函数,看看它们的区别。
comparison.cpp(关键对比)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
“手把手”终端模拟 (结果因机器而异):
1 2 3 4 5 6 7 8 9 |
|
“黄金法则”:
- 当你想知道“我的代码占用了多少 CPU 资源?”(用于算法分析),
clock()可以用(但<chrono>也有 CPU 时钟)。 - 当你想知道“用户等了多久?”(从按下按钮到看到结果),永远使用
std::chrono::high_resolution_clock!这几乎是你 99% 情况下想要的答案。
第四部分:“X光透 视”——观察时间点
auto start_time = high_resolution_clock::now();返回的对象是一个time_point(时间点)。它通常只是一个(非常大的)数字,代表从某个“纪 元”(比如1970年1月1日,或计算机启动时)到现在的纳秒数。