我有两个脚本,每个脚本都计算一个数字的阶乘。我想知道哪个更快。命令time
给出的时间是几毫秒,结果有时不同:
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.089s
user 0m0.052s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.091s
user 0m0.048s
sys 0m0.036s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.088s
user 0m0.048s
sys 0m0.040s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.088s
user 0m0.048s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.087s
user 0m0.064s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.089s
user 0m0.068s
sys 0m0.016s
piousbox@piousbox-laptop:~/projects/trash$
如何计算运行脚本所需的平均时间?我可以解析并平均 100 的输出,time
但我想有更好的解决方案?
答案1
不,你关于平均的想法是正确的。
脚本执行取决于很多因素,但它要分为设置时间(在内存中加载解释器、设置以及可能将代码编译为字节码或机器码)和真实执行时间。
为了更好地关注内部执行时间,您可以在脚本本身中执行循环(即,不是计算一个阶乘,而是在脚本的一次执行中计算 100 次。脚本将设置一次,内部例程将执行 100 次)。
为了关注总时间,您需要执行脚本一百次并取平均值。理想情况下,您应该将这些执行分开足够远,以便系统每次都返回“参考状态”(或与脚本无关的状态)。例如,解释器本身将被缓存在内存中,以便最先脚本的执行将明显比后续脚本慢。
为了更好地了解算法,我认为最好的方法是这样的(在一台空闲的机器上):
- 将算法包装在一个函数中。
- 在控制应用程序中:
- 调用一次函数
- 获取系统(“挂钟”)时间并添加 10(或合理的 N)秒
- 进入循环并开始计算迭代次数
- 每次调用函数后,增加计数器
- 如果系统时间低于保存的时间,则进行另一次循环
- 根据当前挂钟时间获取精确的 N(可能是浮点数)
- 显示计数器除以 N:即每秒的迭代次数。
该应用程序仅运行一次,所有设置和启动都由第一次不计时迭代完成,因此这应该可以最大限度地减少开销(可能除了时间调用)。
如果函数收到输入,你最好使用以固定值作为种子的 PRNG 为其提供随机输入序列,以确保被测试函数的两个版本都收到相同的值。这可以避免一个函数执行显然由于“幸运数字”而更好(例如,我记得 Hillsort 算法的一个变体,当要排序的项目数为 2k-1 形式且较小时,其性能会明显更好钾s)。
答案2
您可以循环运行程序的迭代;然后将总时间除以迭代次数:
time for i in {1..10}; do sleep 1; done
real 0m10.052s
user 0m0.005s
sys 0m0.018s
答案3
有一个工具叫多时间它的作用是:多次运行命令,测量其花费的时间(实际/用户/系统,自动计算平均值、最小值/最大值和中值时间)
例如,测量类似脚本 100 次:
multitime -q -n 100 "fact1.sh"
===> multitime results
1: -q fact1.sh
Mean Std.Dev. Min Median Max
real 0.122 0.032 0.086 0.116 0.171
user 0.148 0.044 0.096 0.137 0.223
sys 0.023 0.019 0.000 0.014 0.061