首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在这种情况下mclappy比应用慢?

为什么在这种情况下mclappy比应用慢?
EN

Stack Overflow用户
提问于 2013-08-08 10:01:55
回答 1查看 803关注 0票数 1

我很困惑。我想通过使用mclapply:parallel,来加速我的算法,但是当我比较时间效率时,应用仍然是胜利。

我正在用rq.fit.fnb:quantreg平滑log2ratio数据,这是由函数quantsm调用的,我正在将数据打包到矩阵/列表中以供apply/lapply(mclapply)使用。

我用这样的方式来说明我的数据:

代码语言:javascript
复制
q = matrix(data, ncol=N)        # wrapping into matrix (using N = 2, 4, 6 or 8)
ql = as.list(as.data.frame(q))  # making list

和时间比较:

代码语言:javascript
复制
apply=system.time(apply(q, 1, FUN=quantsm, 0.50, 2))
lapply=system.time(lapply(ql, FUN=quantsm, 0.50, 2))
mc2lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=2))
mc4lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=4))
mc6lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=6))
mc8lapply=system.time(mclapply(ql, FUN=quantsm, 0.50, 2, mc.cores=8))
timing=rbind(apply,lapply,mc2lapply,mc4lapply,mc6lapply,mc8lapply)

函数quantsm

代码语言:javascript
复制
quantsm <- function (y, p = 0.5, lambda) {
   # Quantile smoothing
   # Input: response y, quantile level p (0<p<1), smoothing parmeter lambda
   # Result: quantile curve

   # Augment the data for the difference penalty
   m <- length(y)
   E <- diag(m);
   Dmat <- diff(E);
   X <- rbind(E, lambda * Dmat)
   u <- c(y, rep(0, m - 1))

   # Call quantile regression
   q <- rq.fit.fnb(X, u, tau = p)
   q
}

函数rq.fit.fnb (quantreg库):

代码语言:javascript
复制
rq.fit.fnb <- function (x, y, tau = 0.5, beta = 0.99995, eps = 1e-06) 
{
    n <- length(y)
    p <- ncol(x)
    if (n != nrow(x)) 
        stop("x and y don't match n")
    if (tau < eps || tau > 1 - eps) 
        stop("No parametric Frisch-Newton method.  Set tau in (0,1)")
    rhs <- (1 - tau) * apply(x, 2, sum)
    d <- rep(1, n)
    u <- rep(1, n)
    wn <- rep(0, 10 * n)
    wn[1:n] <- (1 - tau)
    z <- .Fortran("rqfnb", as.integer(n), as.integer(p), a = as.double(t(as.matrix(x))), 
        c = as.double(-y), rhs = as.double(rhs), d = as.double(d), 
        as.double(u), beta = as.double(beta), eps = as.double(eps), 
        wn = as.double(wn), wp = double((p + 3) * p), it.count = integer(3), 
        info = integer(1), PACKAGE = "quantreg")
    coefficients <- -z$wp[1:p]
    names(coefficients) <- dimnames(x)[[2]]
    residuals <- y - x %*% coefficients
    list(coefficients = coefficients, tau = tau, residuals = residuals)
}

对于长度为2000的数据向量,我得到:

(value =运行时间(秒;列=光滑矩阵/列表的不同列数)

代码语言:javascript
复制
           2cols 4cols 6cols 8cols
apply      0.178 0.096 0.069 0.056
lapply    16.555 4.299 1.785 0.972
mc2lapply 11.192 2.089 0.927 0.545
mc4lapply 10.649 1.326 0.694 0.396
mc6lapply 11.271 1.384 0.528 0.320
mc8lapply 10.133 1.390 0.560 0.260

对于长度为4000的数据,我得到:

代码语言:javascript
复制
            2cols  4cols  6cols 8cols
apply       0.351  0.187  0.137 0.110
lapply    189.339 32.654 14.544 8.674
mc2lapply 186.047 20.791  7.261 4.231
mc4lapply 185.382 30.286  5.767 2.397
mc6lapply 184.048 30.170  8.059 2.865
mc8lapply 182.611 37.617  7.408 2.842

为什么应用比mclapply高效得多?也许我只是犯了些平常的初学者错误。

谢谢你的反应。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-08 13:21:22

看起来,mclapplylapply相比相当不错,但lapplyapply的比较不太好。原因可能是您正在用apply迭代q的行,使用lapplymclapply迭代q的列。这可能是性能差异的原因。

如果确实希望迭代q的行,可以使用以下方法创建ql

代码语言:javascript
复制
ql <- lapply(seq_len(nrow(x)), function(i) x[i,])

如果您想迭代q的列,那么应该按照@flodel的建议,在apply中设置MARGIN=2

lapplymclapply都将迭代数据帧的列,因此您可以使用以下方法创建ql

代码语言:javascript
复制
ql <- as.data.frame(q)

这是有意义的,因为数据框架实际上是一个列表。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18123125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档