我想通过使用move而不是copy来提高下面代码中PickPotatoes
的性能,但我无法弄清楚如何使用insert
和{{1}来做到这一点}}。在我的实际使用案例中,解析数据需要大约75%的时间,而PickPotatoes的真实版本大约需要25%,因为一些缓慢的副本。通过改进boost::variant
,我应该能够做到这一点。是否可以从PickPotatoes
移出某些内容并改进boost::variant
?
PickPotatoes
答案 0 :(得分:1)
最简单的胜利是移动参数值:
std::pair<std::vector<std::string>, std::multimap<int, tuber>> z = PickPotatoes(std::move(q));
事实上,它在性能方面取得了14%的成绩,大致相当于我的基准测试。其余的很大程度上取决于它的意义,它将如何使用。
专注于减少分配(如果可以的话,使用非基于节点的容器,例如boost::flat_multimap
,明确排序,使用string_view,解析到所需的数据结构而不是中间)。
我可以使用以下方法削减约30%的费用:
std::pair<std::vector<std::string>, std::multimap<int, tuber> >
PickPotatoes(std::vector<boost::variant<std::string, tuber> >&& result) {
std::pair<std::vector<std::string>, std::multimap<int, tuber> > ret;
ret.first.reserve(result.size());
struct Vis {
using result_type = void;
void operator()(std::string& s) const {
first.emplace_back(std::move(s));
}
void operator()(tuber& tbr) const {
second.emplace(tbr.z, std::move(tbr));
}
std::vector<std::string>& first;
std::multimap<int, tuber>& second;
} visitor { ret.first, ret.second };
for (auto& element : result) {
boost::apply_visitor(visitor, element);
}
return ret;
}
使用emplace,避免重复get<>
,避免循环获得first
大小等。