R:监控矢量化操作的进度

Ale*_*tov 0 loops r vectorization

是否可以监控向量化操作的进度R?例如,在循环中总是if (i %% 10000) print(i)可以查看代码当前正在处理哪个元素。我的直觉是“可能不是”,但可能是我错了?

李哲源*_*李哲源 5

在我的评论中,我询问了您的代码是什么以及您如何实现矢量化。我认为这很重要。虽然一般来说,矢量化是通过在编译代码中使用循环来实现的,但我并不完全确定这一点。因此,我想不太自信地说“绝对不”。

但是,如果您想在 R 级别跟踪进度,您必须能够获得一个索引,就像i在 R 级别for循环中使用的那样。现在,让我们检查一下大多数 R 向量化函数的样子:

> grep
function (pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, 
    fixed = FALSE, useBytes = FALSE, invert = FALSE) 
{
    if (!is.character(x)) 
        x <- structure(as.character(x), names = names(x))
    .Internal(grep(as.character(pattern), x, ignore.case, value, 
        perl, fixed, useBytes, invert))
}
<bytecode: 0xa34dfe0>
<environment: namespace:base>

> gsub
function (pattern, replacement, x, ignore.case = FALSE, perl = FALSE, 
    fixed = FALSE, useBytes = FALSE) 
{
    if (!is.character(x)) 
        x <- as.character(x)
    .Internal(gsub(as.character(pattern), as.character(replacement), 
        x, ignore.case, perl, fixed, useBytes))
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们看到那些向量化的 R 函数只是编译代码的一个薄包装(参见.Internal())。没有明确的循环索引供您参考。因此,对于那些示例函数,跟踪进度是不可能的。

我建议你看看你使用的特定功能。这是说服自己的最好方法。


跟进

最初,我把lapply我的例子:

> lapply
function (X, FUN, ...) 
{
    FUN <- match.fun(FUN)
    if (!is.vector(X) || is.object(X)) 
        X <- as.list(X)
    .Internal(lapply(X, FUN))
}
<bytecode: 0x9c5c464>
<environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)

然后@RichardScriven 表达了他对*apply家庭的看法。关于堆栈溢出,这两个帖子/答案对于理解 R 中的矢量化问题非常有用:

确实,虽然lapply调用 C 代码来执行循环,但它必须FUN沿着循环评估 R 函数。因此:

  • 如果FUN主宰执行时间,则lapply不会比 R 的for循环有明显的优势。
  • 如果FUN做的工作很少,以至于循环开销主导了执行,那么lapply将比 R 的for循环具有明显的优势,因为forC 中的循环更“轻量级”。

讨论 的性能lapply在这篇文章中是题外话,所以我不会附上例子来演示。