白色空间会减慢处理速度

时间:2013-03-12 17:35:16

标签: r

我需要分析大量数据,在编写代码时,我倾向于在单词或变量名之间留出空间。所以问题是,效率是第一优先级,白空间是否有成本?< / p>

c <-a + b比c < - a + b

更有效

5 个答案:

答案 0 :(得分:8)

对于第一,第二,第三,......,近似,不,它根本不会花费你任何时间。

你按空格键花费的额外时间比运行时的成本高出几个数量级(并且根本没有)。

更重要的成本将来自任何由于遗漏空间而导致的可读性降低,这会使代码更难以解析(对于人类而言)。

答案 1 :(得分:5)

但是,不,不是真的:

TL; DR 运行脚本以删除空格可能需要更长的时间才能删除空白。

@Josh O'Brien确实击中了头部。但我绝不能抗拒基准

正如您所看到的,如果您正在处理1亿个数量级的线路,那么您将看到一个微不足道的阻碍。 HOWEVER 有这么多行,他们很可能至少有一个(如果不是几百个)热点, 简单地改进其中一个中的代码会比grep所有空格更快。

  library(microbenchmark)

  microbenchmark(LottaSpace = eval(LottaSpace), NoSpace = eval(NoSpace), NormalSpace = eval(NormalSpace), times=10e7)

  @ 100 times;  Unit: microseconds
           expr   min     lq median     uq    max
  1  LottaSpace 7.526 7.9185 8.1065 8.4655 54.850
  2 NormalSpace 7.504 7.9115 8.1465 8.5540 28.409
  3     NoSpace 7.544 7.8645 8.0565 8.3270 12.241

  @ 10,000 times;  Unit: microseconds    
           expr   min    lq median    uq      max
  1  LottaSpace 7.284 7.943  8.094 8.294 47888.24
  2 NormalSpace 7.182 7.925  8.078 8.276 46318.20
  3     NoSpace 7.246 7.921  8.073 8.271 48687.72

在哪里:

  LottaSpace <- quote({
        a            <-            3
        b                  <-                  4   
        c         <-      5
        for   (i            in      1:7)
              i         +            i
  })


  NoSpace <- quote({
  a<-3
  b<-4
  c<-5
  for(i in 1:7)
  i+i
  })

  NormalSpace <- quote({
   a <- 3
   b <- 4 
   c <- 5
   for (i in 1:7)
   i + i
  })

答案 2 :(得分:4)

总之,没有!

library(microbenchmark)

f1 <- function(x){
    j   <- rnorm( x , mean = 0 , sd = 1 )         ;
    k   <-      j    *      2         ;
    return(    k     )
}

f2 <- function(x){j<-rnorm(x,mean=0,sd=1);k<-j*2;return(k)}


microbenchmark( f1(1e3) , f2(1e3) , times= 1e3 )
    Unit: microseconds
     expr     min       lq  median      uq      max neval
 f1(1000) 110.763 112.8430 113.554 114.319  677.996  1000
 f2(1000) 110.386 112.6755 113.416 114.151 5717.811  1000

#Even more runs and longer sampling
microbenchmark( f1(1e4) , f2(1e4) , times= 1e4 )
  Unit: milliseconds
      expr      min       lq   median       uq       max neval
 f1(10000) 1.060010 1.074880 1.079174 1.083414 66.791782 10000
 f2(10000) 1.058773 1.074186 1.078485 1.082866  7.491616 10000

修改

似乎使用microbenchmark会不公平,因为表达式在循环运行之前就被解析了。但是,使用source 应该意味着每次迭代都必须解析源代码并删除空格。所以我将函数保存到两个单独的文件中,文件的最后一行是函数的调用,例如我的文件f2.R如下所示:

f2 <- function(x){j<-rnorm(x,mean=0,sd=1);k<-j*2;return(k)};f2(1e3)

我测试它们是这样的:

microbenchmark( eval(source("~/Desktop/f2.R")) ,  eval(source("~/Desktop/f1.R")) , times = 1e3)
  Unit: microseconds
                           expr     min       lq   median      uq       max neval
 eval(source("~/Desktop/f2.R")) 649.786 658.6225 663.6485 671.772  7025.662  1000
 eval(source("~/Desktop/f1.R")) 687.023 697.2890 702.2315 710.111 19014.116  1000

与1e4重复的差异的直观表示.... enter image description here

在重复解析函数的情况下,它可能会产生微小的差异,但在正常用例中不会发生这种情况。

答案 3 :(得分:4)

这可能影响的唯一部分是将源代码解析为令牌。我无法想象解析时间的差异会很大。但是,您可以使用compile包的cmpfuncompiler函数编译函数来消除此方面。然后解析只进行一次,任何空格差异都不会影响执行时间。

答案 4 :(得分:1)

性能应该没有差别,但是:

fn1<-function(a,b) c<-a+b
fn2<-function(a,b) c <- a + b

library(rbenchmark)

> benchmark(fn1(1,2),fn2(1,2),replications=10000000)
       test replications elapsed relative user.self sys.self user.child
1 fn1(1, 2)     10000000   53.87    1.212      53.4     0.37         NA
2 fn2(1, 2)     10000000   44.46    1.000      44.3     0.14         NA

microbenchmark相同:

Unit: nanoseconds
      expr min  lq median  uq      max neval
 fn1(1, 2)   0 467    467 468 90397803 1e+07
 fn2(1, 2)   0 467    467 468 85995868 1e+07

所以第一个结果是假的..