time 命令 #
time
命令用于测量命令或程序的执行时间。它提供了程序运行的实际时间(墙上时钟时间)、用户CPU时间和系统CPU时间等信息,是性能分析和优化的基本工具。
语法 #
time [选项] 命令 [参数...]
常用选项 #
注意:Linux系统中有两种time
命令:shell内置命令和/usr/bin/time
外部命令。外部命令提供更多选项。
Shell内置time(Bash) #
Bash内置的time
命令选项有限:
选项 | 描述 |
---|---|
-p |
使用POSIX格式输出 |
外部time命令(/usr/bin/time) #
外部time
命令提供更多选项:
选项 | 描述 |
---|---|
-f, --format=格式 |
指定输出格式 |
-p, --portability |
使用POSIX格式输出 |
-o, --output=文件 |
将输出写入指定文件而不是标准错误 |
-a, --append |
追加到输出文件而不是覆盖 |
-v, --verbose |
显示详细信息 |
--help |
显示帮助信息 |
--version |
显示版本信息 |
输出说明 #
time
命令的标准输出包含三个主要部分:
-
实际时间(real time):也称为墙上时钟时间(wall clock time),是命令从开始到结束的实际经过时间,包括其他进程使用CPU的时间和I/O等待时间。
-
用户CPU时间(user CPU time):进程在用户模式下执行所花费的CPU时间。
-
系统CPU时间(system CPU time):进程在内核模式下执行所花费的CPU时间,通常用于系统调用和其他内核操作。
常见用法 #
1. 测量命令执行时间(使用shell内置time) #
time ls -la
输出示例:
real 0m0.003s
user 0m0.001s
sys 0m0.002s
2. 使用POSIX格式输出 #
time -p ls -la
输出示例:
real 0.00
user 0.00
sys 0.00
3. 使用外部time命令 #
/usr/bin/time ls -la
输出示例:
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3280maxresident)k
0inputs+0outputs (0major+226minor)pagefaults 0swaps
4. 使用详细输出 #
/usr/bin/time -v ls -la
输出示例:
Command being timed: "ls -la"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 3280
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 226
Voluntary context switches: 1
Involuntary context switches: 0
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
5. 自定义输出格式 #
/usr/bin/time -f "执行时间: %E, CPU使用率: %P, 内存使用: %M KB" ls -la
输出示例:
执行时间: 0:00.00, CPU使用率: 0%, 内存使用: 3280 KB
6. 将结果输出到文件 #
/usr/bin/time -o time_results.txt ls -la
7. 追加结果到文件 #
/usr/bin/time -a -o time_results.txt ls -la
格式说明符 #
使用-f
选项时,可以使用以下格式说明符:
说明符 | 描述 |
---|---|
%E |
实际经过时间([小时:]分钟:秒.毫秒) |
%e |
实际经过时间(秒) |
%S |
系统CPU时间(秒) |
%U |
用户CPU时间(秒) |
%P |
CPU使用百分比((%U + %S) / %E * 100) |
%M |
最大常驻内存大小(KB) |
%t |
平均常驻内存大小(KB) |
%K |
平均总内存使用(数据+栈+文本)(KB) |
%D |
平均非共享数据大小(KB) |
%p |
平均非共享栈大小(KB) |
%X |
平均共享文本大小(KB) |
%Z |
系统页大小(B) |
%F |
主页面错误 |
%R |
次页面错误 |
%W |
交换次数 |
%c |
上下文切换次数(非自愿) |
%w |
上下文切换次数(自愿) |
%I |
文件系统输入 |
%O |
文件系统输出 |
%r |
接收的套接字消息 |
%s |
发送的套接字消息 |
%k |
传递的信号数 |
%C |
被计时的命令名称和参数 |
%x |
命令的退出状态 |
实用示例 #
1. 比较不同算法的执行时间 #
time ./algorithm1
time ./algorithm2
2. 测量编译时间 #
time make
3. 监控脚本性能 #
time ./script.sh
4. 测量数据库查询时间 #
time mysql -u user -p database -e "SELECT * FROM large_table"
5. 测量并记录多次运行的平均时间 #
#!/bin/bash
for i in {1..5}; do
echo "Run $i:"
/usr/bin/time -a -o benchmark.txt -f "%e" ./program
done
echo "Average time: $(awk '{ sum += $1 } END { print sum/NR }' benchmark.txt)"
6. 比较不同参数的影响 #
echo "With optimization:"
time ./program -O3
echo "Without optimization:"
time ./program
7. 测量I/O密集型操作 #
time dd if=/dev/zero of=test.file bs=1M count=1000
8. 测量网络操作 #
time wget http://example.com/largefile.zip
9. 测量并发任务 #
time parallel command ::: input1 input2 input3
10. 测量复杂管道 #
time bash -c "cat large_file.txt | grep pattern | sort | uniq -c | sort -nr > results.txt"
高级用法 #
1. 结合内存分析 #
/usr/bin/time -v ./memory_intensive_program
这将显示详细的内存使用情况。
2. 在脚本中使用time #
#!/bin/bash
start_time=$(date +%s.%N)
# 执行命令
command_to_time
end_time=$(date +%s.%N)
execution_time=$(echo "$end_time - $start_time" | bc)
echo "执行时间: $execution_time 秒"
3. 使用GNU time测量子进程 #
/usr/bin/time -v bash -c "command1 && command2 && command3"
4. 比较并行和串行执行 #
echo "串行执行:"
time (command1 && command2 && command3)
echo "并行执行:"
time (command1 & command2 & command3 & wait)
5. 创建性能基准测试 #
#!/bin/bash
echo "性能基准测试 - $(date)" > benchmark.log
echo "系统信息:" >> benchmark.log
uname -a >> benchmark.log
echo "CPU信息:" >> benchmark.log
cat /proc/cpuinfo | grep "model name" | head -1 >> benchmark.log
echo "内存信息:" >> benchmark.log
free -h >> benchmark.log
echo "测试结果:" >> benchmark.log
/usr/bin/time -a -o benchmark.log -f "\n命令: %C\n实际时间: %E\nCPU使用率: %P\n用户时间: %U\n系统时间: %S\n最大内存: %M KB\n页面错误: %F主/%R次\n上下文切换: %c非自愿/%w自愿" ./program
与其他性能工具的比较 #
工具 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
time | 简单、轻量、几乎所有系统都可用 | 信息有限、不能分析运行中的进程 | 快速测量命令执行时间 |
perf | 详细的CPU和系统性能分析 | 复杂、需要特定权限 | 深入性能分析和优化 |
strace | 详细的系统调用跟踪 | 可能显著减慢程序执行 | 调试系统调用问题 |
valgrind | 内存使用和泄漏分析 | 显著减慢程序执行 | 内存问题调试 |
gprof | 函数级性能分析 | 需要特殊编译选项 | 代码级性能优化 |
提示 #
- 使用外部
/usr/bin/time
命令而不是shell内置time
可以获得更详细的信息 - 多次运行命令并取平均值可以获得更准确的性能测量
- 在测量性能时,尽量减少系统上其他进程的干扰
- 使用
-v
选项可以获取详细的资源使用情况,有助于识别性能瓶颈 - 对于I/O密集型操作,关注实际时间和系统时间
- 对于CPU密集型操作,关注用户时间和CPU使用率
- 使用
time
命令测量性能时,考虑磁盘缓存的影响(第一次运行可能比后续运行慢) - 在性能比较中,确保测试条件一致(相同的系统负载、输入数据等)
- 对于复杂的性能分析,考虑结合使用
time
和其他专业工具(如perf
、strace
等)