如何将项目从boost :: variant移动到多图?

时间:2017-12-04 22:44:46

标签: c++ boost multimap variant

我想通过使用move而不是copy来提高下面代码中PickPotatoes的性能,但我无法弄清楚如何使用insert和{{1}来做到这一点}}。在我的实际使用案例中,解析数据需要大约75%的时间,而PickPotatoes的真实版本大约需要25%,因为一些缓慢的副本。通过改进boost::variant,我应该能够做到这一点。是否可以从PickPotatoes移出某些内容并改进boost::variant

PickPotatoes

1 个答案:

答案 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大小等。