优化r代码

时间:2014-11-17 13:14:10

标签: r statistics

我想优化我的r函数来计算基尼误差:

gini.md<- function(x)
{
  n  = length(x)
  nm = n+1
  x = sort(x)
  return (2/n^2*sum((2*(1:n)-nm)*x))
}

你知道如何让它更快吗?用seq生成seqences很慢。 bitwShiftL((1:n), 1)2* (1:n)慢。怎么可能?

此外,我发现mean(x)sum(x)/length(x)慢。再次为什么???均值是一个内部函数它应该更快。

1 个答案:

答案 0 :(得分:1)

忽略了我自己的建议,我猜测任何速度问题的最可能的来源是不必要地创建长向量。以下C实现避免了创建四个向量(1:n2 * (1:n)2 * (1:n) - nm,最后是(2*(1:n)-nm)*x)。

library(inline)
gini <- cfunction(signature(x="REALSXP"), "
    double n = Rf_length(x), nm = n + 1, ans = 0;
    const double *xp = REAL(x);
    for  (int i = 0; i < n; ++i)
        ans += (2 * (i + 1) - nm) * xp[i];
    return ScalarReal(2 * ans / (n * n));
")

但这似乎没什么帮助。我意识到评估时间由sort()支配。

> library(microbenchmark)
> x <- rnorm(100000)
> all.equal(gini.md(x), gini(sort(x)))
[1] TRUE
> microbenchmark(gini.md(x), gini(sort(x)), sort(x), times=10)
Unit: milliseconds
          expr       min       lq     mean   median       uq      max neval
    gini.md(x) 10.668591 10.98063 11.09274 11.03377 11.20588 11.62714    10
 gini(sort(x)) 10.439458 10.64972 10.78242 10.70099 10.93015 11.36177    10
       sort(x)  9.995886 10.18180 10.31508 10.27024 10.46160 10.66006    10

也许有更多的速度,但它也同样是边缘的。