【发布时间】:2013-05-10 19:51:51
【问题描述】:
我希望只从容器中获取唯一元素。假设srcContainer 是我想要独特元素的容器。我看了三个选项:
-
使用 std::unique
std::sort(srcContainer.begin(), srcContainer.end()); srcContainer.erase(std::unique(srcContainer.begin(), srcContainer.end()), srcContainer.end()); -
使用 BOOST::unique
boost::erase(srcContainer, boost::unique<boost::return_found_end>(boost::sort(srcContainer))); -
我自己的方法
std::set<T> uniqueElems(srcContainer.begin(), srcContainer.end()); srcContainer.clear(); srcContainer.insert(srcContainer.end(), uniqueElems.begin(), uniqueElems.end());
1. 和 2. 的问题是它们改变了成员在原始 srcContainer 中出现的顺序。与 3. 相比,顺序没有变化,此外,与上面的 1. 和 2 相比,它提供了更好的性能(是不是因为 3. ?? 中没有明确的排序)。上面 3 种方法的挂钟时间和 srcContainer 中的元素数量如下:
srcContainer 的大小(包含整数)= 1e+6
- std::unique = 1.04779 秒
- BOOST::unique = 1.04774 秒
- 自己的方法 = 0.481638 秒srcContainer 的大小(包含整数)= 1e+8
- std::unique = 151.554 秒
- BOOST::unique = 151.474 秒
- 自己的方法 = 57.5693 秒
我的问题是:
- 是否有更好的方法使用 std::unique 或 BOOST::unique 或任何其他代码查找唯一性并保持容器中的原始顺序?
- 使用上述方法 3. 的任何问题。
对于性能分析srcContainer 创建如下:
std::vector<int> srcContainer;
int halfWay = numElems/2;
for (size_t k=0; k<numElems; ++k) {
if (k < halfWay)
srcContainer.push_back(k);
else
srcContainer.push_back(k - halfWay);
}
编辑:
同意cmets,方法3.也改变了元素的顺序。有没有更好的方法在不改变顺序的情况下获得独特的元素?
谢谢
【问题讨论】:
-
srcContainer的类型是什么?
-
在这种情况下,我使用 srcContainer 的向量进行测试。但我希望代码适用于大多数容器类型,例如 BOOST::unique。
-
我只是感兴趣:容器有多大?您是否分析了代码,瓶颈在哪里?你用的是什么平台?从极长的执行时间来看,我认为瓶颈在于创建来自 std::unique 而不是排序的大型容器的副本。
-
您可以在调试模式 (g++ -g) 编译代码后使用 'valgrind --tool=kcachegrind' 分析代码,而无需开启优化。然后你可以使用 kcachegrind 找到瓶颈。
-
谢谢。列出的运行时间仅适用于显示的部分代码。不包括创建 srcContainer 所花费的时间。上面列出了 srcContainer 的大小。