【发布时间】:2016-05-05 20:46:22
【问题描述】:
我有两个正整数向量指定范围的开始和结束“位置”
starts <- sample(10^6,replace = T)
ends <- starts+sample(100:1000,length(starts),replace=T)
因此,这些指定了 1000000 个范围,长度为 100 到 1000 个单位。 现在我想知道一个位置(正整数)被一个范围“覆盖”了多少次。为此,我这样做:
coverage <- integer(max(ends))
for(i in seq(length(starts))) {
coverage[starts[i]:ends[i]] <- coverage[starts[i]:ends[i]] + 1
}
但是因为有for循环,所以比较慢。对于数十亿个范围,可能需要很长时间。 我找不到向量化此代码的方法。我可以拆分工作并使用多个 CPU,但速度增益将是微不足道的。 apply、lapply 和其他元函数不会提高速度(如预期的那样)。比如
coverage <- tabulate(unlist(Map(':', starts,ends)))
由于“地图”部分,它也很慢。我担心它也需要更多的内存。
有什么想法吗?
【问题讨论】:
-
如何运行
density,在开始 + 50 时有一个矩形窗口 -
但范围的大小可能并不总是相同的。我编辑了我的代码以明确这一点。
-
您的主要问题可能不是循环或
Map,而是:功能。对它进行矢量化似乎确实是一个非常频繁的请求...对可重现的示例和不错的尝试表示敬意。尽管您实际上并不需要10^6来创建一个 minimal 可重现的示例。在创建具有使用随机种子的函数的数据集时,添加set.seed始终是一个好习惯。此外,显示所需的输出使阅读更容易(尽管在您的情况下这并不是什么大不了的事)。 -
如果我在
Map调用中将:替换为+,它仍然比简单的starts+ends慢得多。所以 Map 比矢量化代码慢。 -
这不是关于
Map,而是关于你需要评估一个函数的次数+该函数的效率。如果将:替换为+,在我的机器上大约需要一秒钟(而:需要7 秒钟)。对一个函数进行 1e6 次评估并不是 那么 不好。在更糟糕的情况下,您可以在 Rcpp 中为:编写一个矢量化版本并克服。
标签: r performance