为啥插入 set<vector<string>> 这么慢?
Posted
技术标签:
【中文标题】为啥插入 set<vector<string>> 这么慢?【英文标题】:Why is inserting into a set<vector<string>> so slow?为什么插入 set<vector<string>> 这么慢? 【发布时间】:2016-12-02 21:08:50 【问题描述】:对于一个类项目,我们正在制作一个简单的编译器/关系数据库。我的产生正确答案,但在大型查询中速度太慢。我运行了 Visual Studio 的性能分析,我的程序花费了 80% 的时间将我的元组(表格中的行)插入到一个集合中。该函数是计算叉积的一部分,因此结果有很多很多行,但我需要有关将元组插入集合的更快方法的建议。
for (set<vector<string>>::iterator it = tuples.begin(); it != tuples.end(); ++it)
for (set<vector<string>>::iterator it2 = tuples2.begin(); it2 != tuples2.end(); ++it2)
vector<string> f(*it);
f.insert(f.end(), it2->begin(), it2->end());
newTuples.insert(f); //This is the line that takes all the processing time
【问题讨论】:
什么是newTuples
?
您的向量是在每次插入时通过复制创建的。使用指针和新的。
@PierreEmmanuelLallemant,多么糟糕的建议……
@SergeyA:不知道 std::move,ty。
newTuples 是我正在制作的新表中的所有行。
【参考方案1】:
您无缘无故地按值复制大向量。你应该移动:newTuples.insert(std::move(f));
【讨论】:
有道理,但对函数花费的时间没有影响。向量不是很大(最多 20 项)【参考方案2】:set
可能是错误的容器。 set
是有序的,并且只保留唯一的元素。当您插入一个新的vector
时,可能会发生许多string
比较。
改用list
或vector
(如果可以的话)。
...避免不必要的复制,正如 SergeyA 在他的回答中已经指出的那样
【讨论】:
你可能是对的,我最初使用一组作为摆脱重复项的简单方法。现在更改它需要大量重构,并且可能不值得我的 1% 的成绩。【参考方案3】:我们还不如去 C++11(完全未经测试的代码)
for (const auto& it : tuples)
for (const auto& it2 : tuples2)
auto where = newTuples.emplace(it); // returns where its placed
auto& vect = where.first; // makes the next more readable
vect.insert(vect.end(), it2.begin(), it2.end());
注意碰撞,一些字符串会从结果中消失,这真的是你想要的吗? 您使用向量作为键,这会不会是碰撞?添加
if (!where.second)
; // collision
检查。
这应该消除所有移动的双重工作(如果编译器无论如何都没有优化它)。
【讨论】:
以上是关于为啥插入 set<vector<string>> 这么慢?的主要内容,如果未能解决你的问题,请参考以下文章