【发布时间】:2017-07-11 02:50:45
【问题描述】:
我正在尝试编写一个函数来计算字符串向量中唯一项的数量(我的问题稍微复杂一些,但这是可重现的。我是根据我为 C++ 找到的答案做的。这是我的代码:
C++
int unique_sort(vector<string> x) {
sort(x.begin(), x.end());
return unique(x.begin(), x.end()) - x.begin();
}
int unique_set(vector<string> x) {
unordered_set<string> tab(x.begin(), x.end());
return tab.size();
}
R:
x <- paste0("x", sample(1:1e5, 1e7, replace=T))
microbenchmark(length(unique(x)),unique_sort(x), unique_set(x), times=3)
结果:
Unit: milliseconds
expr min lq mean median uq
length(unique(x)) 365.0213 373.4018 406.0209 381.7823 426.5206
unique_sort(x) 10732.1918 10847.0532 10907.6882 10961.9146 10995.4363
unique_set(x) 1948.6517 2230.3383 2334.4040 2512.0249 2527.2802
查看unique 函数的 R 源代码(有点难以理解),它似乎使用数组上的循环将唯一元素添加到散列,并检查该散列是否已经存在。
因此,我认为它应该等效于 unordered_set 方法。我不明白为什么 unordered_set 方法慢了 5 倍。
TLDR:为什么我的 C++ 代码很慢?
【问题讨论】:
-
什么是“高度优化的编译代码”,如何实现? Rcpp 已经编译。也可以将其他函数编写为与已编译的 R 代码(例如,制表函数)的性能相同。我觉得我错过了一些慢 5 倍的算法。
-
Dirk 解释得更好here。我认为这是一个类似的情况。
-
在那篇文章中,由于开销引起的差异以纳秒为单位,在这里差异为秒时并不特别相关。我可以向您展示其他 R 函数,其中差异远小于秒。
-
我知道这并不能回答你关于为什么的问题,但这里有一个
Rcpp函数,它比基本 R 快 5 倍:int unique_size(CharacterVector x) {return Rcpp::unique(x).size();}。我一直在查看源代码,但实际上找不到任何东西。确实很有趣。 -
谢谢,非常感谢。希望有人能回答“为什么”的问题:)