......关于执行时间和/或记忆.
如果不是这样,请使用代码段进行证明.请注意,矢量化的加速不计算在内.增速必须来自apply(tapply,sapply,...)本身.
因此,我们习惯于对每个R新用户说" apply没有矢量化,请查看Patrick Burns R Inferno Circle 4 ",其中说(我引用):
常见的反射是使用apply系列中的函数.这不是 矢量化,而是循环隐藏.apply函数在其定义中有一个for循环.lapply函数掩盖了循环,但执行时间往往大致等于显式for循环.
实际上,快速查看apply源代码会显示循环:
grep("for", capture.output(getAnywhere("apply")), value = TRUE)
## [1] " for (i in 1L:d2) {" " else for (i in 1L:d2) {"
Run Code Online (Sandbox Code Playgroud)
好到目前为止,但看看lapply或vapply实际上揭示了一个完全不同的图片:
lapply
## function (X, FUN, ...)
## {
## FUN <- match.fun(FUN)
## if (!is.vector(X) || is.object(X))
## X <- as.list(X)
## .Internal(lapply(X, FUN))
## }
## <bytecode: 0x000000000284b618>
## <environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)
所以显然没有R for环隐藏在那里,而是他们调用内部C编写的函数.
此外,让我们以 …
也许这个问题非常愚蠢.
我试图"矢量化"以下循环:
set.seed(0)
x <- round(runif(10), 2)
# [1] 0.90 0.27 0.37 0.57 0.91 0.20 0.90 0.94 0.66 0.63
sig <- sample.int(10)
# [1] 1 2 9 5 3 4 8 6 7 10
for (i in seq_along(sig)) x[i] <- x[sig[i]]
x
# [1] 0.90 0.27 0.66 0.91 0.66 0.91 0.94 0.91 0.94 0.63
Run Code Online (Sandbox Code Playgroud)
我认为这很简单,x[sig]但结果并不匹配.
set.seed(0)
x <- round(runif(10), 2)
x[] <- x[sig]
x
# [1] 0.90 0.27 0.66 0.91 0.37 0.57 0.94 0.20 0.90 0.63
Run Code Online (Sandbox Code Playgroud)
怎么了?
备注 …
在R中给出这样的数据帧:
+---+---+
| X | Y |
+---+---+
| 1 | 2 |
| 2 | 4 |
| 4 | 5 |
+---+---+
Run Code Online (Sandbox Code Playgroud)
如果对此数据帧执行矢量化操作,如下所示:
data$Z <- data$X * data$Y
Run Code Online (Sandbox Code Playgroud)
这会利用处理器的单指令多数据(SIMD)功能来优化性能吗?这似乎是一个完美的案例,但我找不到任何证实我的预感的东西.
考虑以下玩具示例,其中A是以n x 2列主要顺序存储的矩阵,我想计算其列总和.sum_0仅计算第1列的总和,同时sum_1也计算第2列的总和.这实际上是一个人为的例子,因为基本上不需要为这个任务定义两个函数(我可以编写一个带有双循环嵌套的函数,其中外循环从中迭代0到j).它的构建是为了演示我现实中的模板问题.
/* "test.c" */
#include <stdlib.h>
// j can be 0 or 1
static inline void sum_template (size_t j, size_t n, double *A, double *c) {
if (n == 0) return;
size_t i;
double *a = A, *b = A + n;
double c0 = 0.0, c1 = 0.0;
#pragma omp simd reduction (+: c0, c1) aligned (a, b: 32)
for (i = 0; i < …Run Code Online (Sandbox Code Playgroud) x <- 1:9
names(x) <- paste0("x",x)
y <- 2:5
names(y) <- paste0("y",y)
fun1 <-function(a, b) {paste(class(a),b, sep = "**")} #works
funError <-function(a, b) {paste(class(a),class(b), sep = "**")} #does not work with outer
funNoError<-function(a, b) {paste(a,class(a),class(b),b, sep = "**")} #works with outer
funError(1,2) #is a valid function
outer(x, y, "funError") # fails
outer(x, y, "funNoError") # works
Run Code Online (Sandbox Code Playgroud)
Q1:为什么不起作用outer(x, y, "funError")?
dim(robj) <- c(dX, dY) 中的错误:dims [产品 36] 与对象 [1] 的长度不匹配
Q2:为什么outer(x, y, "funNoError")有效?它非常相似。
我能看到的唯一区别是,的每个“结果”funError …