R中的计时功能


36
  1. 我想测量重复执行功能所花费的时间。是否replicate()使用for循环等价?例如:

    system.time(replicate(1000, f()));
    system.time(for(i in 1:1000){f()});

    首选方法。

  2. 在的输出中system.time(),是sys+user运行该程序的实际CPU时间吗?是否elapsed可以很好地衡量程序的时间性能?


3
仅作记录,因为我显然改变该问题的过程为时已晚:我认为这是最适合StackOverflow的问题。
马特·帕克

2
@Matt我同意关于程序如何适合SO的问题。我也同意,对这个问题的字面解释(由若干答案得出)将使它偏离简历的主题。不过,在设计计时实验和分析此类实验的结果时似乎确实有一些统计上的兴趣。
ub

Answers:


19

为了使程序更有效,尤其是在您有兴趣比较替代解决方案时,您需要一个控件!一个好的方法是将要计时的过程放入函数中。在定时循环内调用该函数。编写一个存根过程,本质上是从函数中剥离所有代码并从中返回(但保留所有参数)。将存根放入您的计时循环并重新计时。这将测量与计时相关的所有开销。从过程时间中减去存根时间以获得净值:这应该是实际所需时间的准确度量。

NmN/m

通过使用实验设计的这些基本原理,您基本上可以控制由于代码部署方式而引起的任何差异(例如,for循环和plicate()之间的差异)。那使您的问题消失了。


25

关于您的两点:

  1. 它的风格。我喜欢replicate()它的功能。
  2. 我倾向于关注elapsed,即第三个数字。

我经常做的是

N <- someNumber
mean(replicate( N, system.time( f(...) )[3], trimmed=0.05) )

以获得N次通话重复次数的90%的均值f()

(编辑,感谢哈德利抓住了思想家。)


2
不是mean(replicate(N, system.time(f(...))[3]), trim = 0.05)
哈德利2010年

2
如果f()调用很长,那很好。但是,如果f()调用很短,则任何定时调用开销都可能会增加错误度量。在多次重复f()的情况下,一次调用system.time()即可将错误除以该调用,直到达到某个无穷小值为止(并且返回速度更快)。
约翰

@约翰:谢谢,但我不太理解你的意思。我仍然想知道哪个更好,在system.time()内部或外部重复f()?
蒂姆(Tim)

每次对system.time()命令的调用都具有一定的可变时间,这会导致一定量的测量错误。这是少量。但是,如果f()是一个非常简短的调用怎么办?然后,可以将此错误与调用f()的时间混淆。因此,当您在单个system.time()内调用f()1e5次时,错误将分为1e5块。当您为每个f()调用system.time()时,如果f()的时间很小,则其影响可能是有意义的。当然,如果您需要的只是相对定时,那就没关系了。
约翰

哦,第二部分是只调用system.call()会更快。
约翰

10

您还可以根据返回的时间步长进行计时Sys.time。这当然会测量墙壁时间,因此是实时计算时间。示例代码:

Sys.time()->start;
replicate(N,doMeasuredComputation());
print(Sys.time()-start);


1

他们做不同的事情。时间您想要完成的事情。plicate()返回函数每次执行结果的向量。for循环没有。因此,它们不是等效的语句。

此外,您还可以通过多种方式来完成某件事。然后,您可以找到最有效的方法。


mod-tip:将第二部分作为对Dirk答案的评论。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.