【计时方法】四、UNIX 的 time 命令

现在让我们脱离 Python,使用类 UNIX 操作系统的标准系统功能。下面这条命令会记录程序执行所耗费的各方面时间,且不在意代码的内部结构:

$ /usr/bin/time -p python test.py
real 13.46
user 13.40
sys 0.04

注意我们特地使用了 /usr/bin/time 而不是 time,也就是说我们使用的是系统命令的 time 而不是那个更加简单而没用的 shell 内建版本的 time。

通过使用 -p 开关,我们得到了 3 个结果:
* real 记录了整体的耗时。
* user 记录了 CPU 花在任务上的时间,但不包括内核函数耗费的时间。
* sys 记录了内核函数耗费的时间。

将 user 和 sys 相加就得到了 CPU 总共花费的时间。而这个时间和 real 的差也有可能是花费在等待 IO 上,也可能是系统正在忙着运行其他任务因此影响了刚才的测量。

time 并不是专为 Python 脚本使用的。它还包括了启动 python 解释器的时间,如果你会启动很多新进程(而不是一个长期运行的单一进程),这个时间可能会很长。如果你会经常跑一些临时脚本,它们的启动时间占了整体运行时间的很大一部分,那么 time 更适合测量这种情况。

我们可以打开–verbose 开关来获得更多输出信息:

$ /usr/bin/time --verbose python test.py
Command being timed: "python test.py"
User time (seconds): 13.46
...
Major (requiring I/O) page faults: 0
...

这里最有用的指标可能是 Major (requiring I/O) page faults,因为它指示了操作系统是否由于 RAM 中的数据不存在而需要从磁盘抢读取页面。而这会带来速度上的惩罚。

我们的例子中对于代码和数据的需求较少,所以不会发生内存错误。如果你有一个内存密集型进程,或多个需要分配和使用大量 RAM 的进程,你就会发现这个命令可以告诉你哪个进程会因为一部分 RAM 被交换到磁盘上这一额外的操作系统级别的磁盘访问而导致速度的下降。