r-为什么在这种情况下mclappy比apply慢



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

我正在通过函数quansm调用的rq.fit.fnb:quantreg平滑log2ratio数据,并将数据包装到矩阵/列表中,以供apply/lapply(mclapply)使用。

我这样调整我的数据:

q = matrix(data, ncol=N)        # wrapping into matrix (using N = 2, 4, 6 or 8)
ql = as.list(as.data.frame(q))  # making list

时间比较:

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 <- 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库):

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的数据矢量,我得到:

(值=以秒为单位的经过时间;列=平滑矩阵/列表的不同列数)

           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的数据,我得到:

            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更有效?也许我只是犯了一些初学者常犯的错误。

谢谢你的反应。

看起来mclapplylapply的比较非常好,但lapplyapply的比较不好。原因可能是用apply迭代q的行,用lapplymclapply迭代q的列。这可能是性能差异的原因。

如果您真的想迭代q的行,您可以使用:创建ql

ql <- lapply(seq_len(nrow(x)), function(i) x[i,])

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

lapplymclapply都将在数据帧的列上迭代,因此您可以使用:创建ql

ql <- as.data.frame(q)

这是有道理的,因为数据帧实际上是一个列表。

最新更新