R 我的system.time包装器函数有问题吗?

R 我的system.time包装器函数有问题吗?,r,R,编辑:由于@daroczig在下面给出了可爱的答案,所以更新了。然而,测试2仍然感觉比测试1需要更长的时间,这正是我所想的。 更新:在二读时,@daroczig的回答确实解释了我的困惑——这个问题是因为我没有正确地思考系统时间(expr)代码行。 我想制作一个版本的system.time函数,在理解运行到运行时间波动方面,它对我自己会有更多的信息: system.time.summary <- function(N, expr) { t.mat <- replicate(N, s

编辑:由于@daroczig在下面给出了可爱的答案,所以更新了。然而,测试2仍然感觉比测试1需要更长的时间,这正是我所想的。

更新:在二读时,@daroczig的回答确实解释了我的困惑——这个问题是因为我没有正确地思考系统时间(expr)代码行。

我想制作一个版本的
system.time
函数,在理解运行到运行时间波动方面,它对我自己会有更多的信息:

system.time.summary <- function(N, expr) {
  t.mat <- replicate(N, system.time(expr))
  as.data.frame(apply(t.mat[1:3,], 1, summary))
}
我希望我能解释清楚!可能现在是星期一早上,但这让我很困惑

我的系统:

# Windows Server 2008 R2
> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: x86_64-pc-mingw32/x64 (64-bit)

在第一次测试中,您正在运行
system.time(system.time())
,并且在函数中使用
system.time(1:1e8)^2+1)
作为表达式,这不是一个好主意,请参阅:

> expr <- system.time((1:1e8)^2 + 1)
> system.time(expr)
   user  system elapsed 
      0       0       0 
expr系统时间(expr) 用户系统运行时间 0 0 0 但无论如何:使用CRAN提供的包装用于此类目的,您不会后悔。设置不同的功能,您可以轻松地进行100次、1000次或任意运行的模拟。在基准测试结束时,您可以得到一个简洁的摘要和方框图

例如:

> test1 <- function() (1:1e8)^2 + 1
> (results <- microbenchmark(test1(), times=10))
Unit: nanoeconds
               min         lq     median         uq        max
test1() 3565386356 3703142531 3856450582 3931033077 3986309085
> boxplot(results)
>test1(结果箱线图(结果))

正如达罗奇格所说,你有一个额外的系统。时间。但还有一些东西:

如果在函数中放置一个
browser()
,您就会看到发生了什么。事实上,您创建的表达式只计算一次,然后保存在内存中。这是R内部优化的方式。因此,如果您这样做:

system.time.summary(N,(1:1e8)^2 +1)
t、 mat在内部是:

           [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
user.self  0.61    0    0    0    0    0    0    0    0     0
sys.self   0.36    0    0    0    0    0    0    0    0     0
elapsed    0.97    0    0    0    0    0    0    0    0     0
user.child   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
sys.child    NA   NA   NA   NA   NA   NA   NA   NA   NA    NA
expr是:

Browse[2]> str(expr)
 num [1:100000000] 2 5 10 17 26 37 50 65 82 101 ...
改变这一点有点困难,因为R只对任何静态表达式求值一次,然后再从内存中检索99次结果。如果不想发生这种情况,必须显式传递表达式,并添加
eval()
函数:

system.time.summary <- function(N, expr) {
  t.mat <- replicate(N, system.time(eval(expr)))
  as.data.frame(apply(t.mat[1:3,], 1, summary))
}

system.time.summary(N, expression((1:1e8)^2 + 1))
这将为您提供正确的计时

        user.self sys.self elapsed
Min.       0.6400   0.2000   0.970
1st Qu.    0.6850   0.2375   0.980
Median     0.7150   0.2700   0.985
Mean       0.7130   0.2700   0.985
3rd Qu.    0.7425   0.2975   0.990
Max.       0.7800   0.3500   1.000

我的天哪,我不知道有一个microbenchmark软件包,谢谢!你在第一次测试中对系统的认识是非常正确的。时间(system.time()),但即使我删除了它,测试2仍然感觉比测试1长。重新阅读你的答案,我相信它确实回答了我的问题,因为我没有正确地思考系统。时间(expr)代码行。答案被接受,非常感谢您的时间和帮助。在您的函数中,expr只被计算一次,在函数之外,表达式被计算n次。我接受@Joris Meys答案,因为它充分解释了所有内容并更正了我的初始代码,但您的答案也很棒,特别是对于了解麦克风罗伯特马克包裹!:)@Tony Breyal:没错,复选标记肯定应该在那里我也从@Joris Meys的答案中学到了很多!等等,你是说我基本上可以在R内部调试?我不知道!有多少R是我不知道的…@托尼:如果你不知道,那么现在是时候看看:?回溯、?调试、?调试一次、?浏览器,以及(加上你在网站上找到的所有其他使用
[R]debug
作为搜索词的)享受:-)为那个伙伴干杯,看来我得花点时间来阅读所有这些我从未听说过的非常有趣、非常有用的函数了!:)太棒了,谢谢你的帖子!我从上面的代码中学到了很多。
Browse[2]> expr
expression((1:1e+08)^2 + 1)
        user.self sys.self elapsed
Min.       0.6400   0.2000   0.970
1st Qu.    0.6850   0.2375   0.980
Median     0.7150   0.2700   0.985
Mean       0.7130   0.2700   0.985
3rd Qu.    0.7425   0.2975   0.990
Max.       0.7800   0.3500   1.000