我一直在运行欧拉项目,试图编写计算效率高的程序。考虑问题1:http://projecteuler.net/problem=1 http://projecteuler.net/problem=1。我将范围从 1000 提高到 10,000,000 以突出效率低下的情况。
这是我的解决方案:
system.time({
x <- 1:1E7
a <- sum(as.numeric(x[x%%3 ==0 | x%%5==0]))
})
user system elapsed
0.980 0.041 1.011
这是朋友编写的一些 C++ 代码,用于执行相同的操作。
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
long x = 0;
for (int i = 1; i < 10000000; i++)
{
if (i % 3 == 0)
x += i;
else if (i % 5 == 0)
x += i;
}
cout << x;
return 0;
}
cbaden$ time ./a.out
23333331666668
real 0m0.044s
user 0m0.042s
sys 0m0.001s
我知道 C++ 应该比 R 更快,但是this快多了? Rprof 指出,我将近 60% 的时间花在模运算符上,13% 的时间花在“==”运算上。有没有矢量化的方法可以更快地做到这一点?
第二个担心是我会耗尽内存——随着范围变大,这种方法的可扩展性不太好。有没有一种好方法可以保留可矢量化性,但不会尝试将子集保留在内存中?
模数运行时速度更快integer
是而不是numeric
s:
f1 <- function() {
x <- 1:1E7
a <- sum(as.numeric(x[x%%3 ==0 | x%%5==0]))
}
f2 <- function() {
x <- 1:1E7
a <- sum(as.numeric(x[x %% 3L == 0L | x %% 5L == 0L]))
}
library(rbenchmark)
benchmark(f1(), f2(), replications = 5)
# test replications elapsed relative user.self sys.self user.child sys.child
# 1 f1() 5 14.78 4.976431 13.95 0.67 NA NA
# 2 f2() 5 2.97 1.000000 2.37 0.50 NA NA
这距离 C++ 的性能还很远,但这是朝着正确方向迈出的一步。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)