为什么矢量化更快

时间:2013-06-03 17:58:47

标签: r vectorization

我已经学习了R一段时间了,并且已经为像我这样的编程类型提出了很多建议来进行矢量化操作。作为一名程序员,我对它为何/如何更快感兴趣。一个例子:

n = 10^7
# populate with random nos
v=runif(n)
system.time({vv<-v*v; m<-mean(vv)}); m
system.time({for(i in 1:length(v)) { vv[i]<-v[i]*v[i] }; m<-mean(vv)}); m

这给了

   user  system elapsed 
   0.04    0.01    0.07 
[1] 0.3332091

   user  system elapsed 
  36.68    0.02   36.69 
[1] 0.3332091

最明显的事情是我们正在运行本机代码,即从C或C ++编译的机器代码,而不是解释代码,如两个示例之间用户时间的巨大差异所示(大约3个订单)大小)。但还有什么事吗?例如,R会这样做:

  • 狡猾的原生数据结构,例如存储稀疏向量或矩阵的巧妙方法,以便我们只在需要时进行乘法运算?

  • 懒惰评估,例如在矩阵乘法上,不要在需要时评估单元格。

  • 并行处理。

  • 其他。

为了测试是否存在稀疏矢量优化,我尝试使用差异矢量内容进行点积

# populate with random nos
v<-runif(n)
system.time({m<-v%*%v/n}); m
# populate with runs of 1 followed by 99 0s
v <-rep(rep(c(1,rep(0,99)),n/100))
system.time({m<-v%*%v/n}); m
# populate with 0s
v <-rep(0,n)
system.time({m<-v%*%v/n}); m

然而,时间上没有显着差异(大约经过0.09)

(Matlab的相似问题:Why does vectorized code run faster than for loops in MATLAB?

3 个答案:

答案 0 :(得分:10)

  

最明显的事情是我们正在运行本机代码,   即从C或C ++编译的机器代码,而不是解释   代码

这就是大部分内容。另一个重要的组成部分是,由于R代码在其设计范例中起作用,函数(尝试)没有副作用,这意味着在某些(但可能不是全部; R 尝试这样做有效率)在for循环中调用[<-的实例导致必须复制整个对象。 可能会变慢。

一个小旁注:R确实具有相当广泛的功能,可以有效地处理sparse矩阵结构,但它们不是“默认”。

答案 1 :(得分:7)

您在两个示例中都运行了解释代码和本机代码。不同之处在于,在第二个阶段,您在R级别进行循环,导致需要解释的更多函数调用,然后调用C代码。在你的第一个例子中,循环发生在已编译的代码中,因此R的解释要少得多,R代码调用的次数要少得多,对编译代码的调用也少得多。

答案 2 :(得分:4)

关于并行处理,开箱即用的R不进行任何并行处理。当然有内置的parallel包,但您必须调整代码以使用例如mclapply使用并行处理。有一些选项可以让你的线性代数使用blas的特殊版本并行计算,但这在R中并不是标准使用,尽管让它起作用似乎并不难。