【发布时间】:2018-06-29 09:27:04
【问题描述】:
下面的 Julia 和 R 中的代码是为了表明总体方差的估计量是有偏的估计量,即它取决于样本量,并且无论我们对不同的观察平均多少次,对于少量数据点它不等于总体的方差。
Julia 大约需要 10 秒才能完成两个循环,而 R 大约需要 7 秒。
如果我将代码留在注释的循环中,那么 R 和 Julia 中的循环将花费相同的时间,并且如果我只将迭代器相加 s = s + i+ j Julia 将在 ~0.15 秒内完成,R 在 ~0.5 秒内完成。
是 Julia 循环变慢还是 R 变快了? 如何为 Julia 提高以下代码的速度? R代码可以变快吗?
朱莉娅:
using Plots
trials = 100000
sample_size = 10;
sd = Array{Float64}(trials,sample_size-1)
tic()
for i = 2:sample_size
for j = 1:trials
res = randn(i)
sd[j,i-1] = (1/(i))*(sum(res.^2))-(1/((i)*i))*(sum(res)*sum(res))
end
end
toc()
sd2 = mean(sd,1)
plot(sd2[1:end])
R:
trials = 100000
sample_size = 10
sd = matrix(, nrow = trials, ncol = sample_size-1)
start_time = Sys.time()
for(i in 2:sample_size){
for(j in 1:trials){
res <- rnorm(n = i, mean = 0, sd = 1)
sd[j,i-1] = (1/(i))*(sum(res*res))-(1/((i)*i))*(sum(res)*sum(res))
}
}
end_time = Sys.time()
end_time - start_time
sd2 = apply(sd,2,mean)
plot(sqrt(sd2))
我可以实现更高速度的一种方法是使用在 Julia 中很容易实现的并行循环:
using Plots
trials = 100000
sample_size = 10;
sd = SharedArray{Float64}(trials,sample_size-1)
tic()
@parallel for i = 2:sample_size
for j = 1:trials
res = randn(i)
sd[j,i-1] = (1/(i))*(sum(res.^2))-(1/((i)*i))*(sum(res)*sum(res))
end
end
toc()
sd2 = mean(sd,1)
plot(sd2[1:end])
【问题讨论】:
-
在
R我愿意:my.sd <- function(i) {; res <- rnorm(n = i, mean = 0, sd = 1); mean(res*res) - mean(res)^2; }; sd <- replicate(trials, sapply(2:sample_size, my.sd)) -
将其包装在一个函数中后,您会发现几乎所有时间都花在
randn中,它与 Julia vs R 中的循环速度无关。您也在写sum(res)*sum(res)代替sum(res)^2,sum(res.^2)代替sum(abs2, res),都是浪费资源。你可以改写成这样:sd[j, i-1] = sum(abs2, res) / i - (sum(res) / i)^2. -
@DNF,所有这些都是正确的,但另外在 Julia 中,在全局范围内执行时也会循环自己,比在函数中执行的循环慢。
标签: r performance loops julia