如何(有效地)将地图作为值插入到地图中?

时间:2015-10-11 13:32:04

标签: c++ performance insert unordered-map

我正在编写一个C ++程序,逐行读取大文件,并将每个line-info(经过一些处理后)插入到unordered_map中。

这是unordered_map的声明:

unordered_map<int, unordered_map<int, int> > entries;

我做的插入是(这是在循环代码块中,我处理文本文件的每一行):

unordered_map<int, int> tmp;
tmp[y] = z;
entries[x] = tmp;

但事实证明,这在表现方面表现不佳。

我尝试创建pair<int, pair<int, int>>并使用entries.insert(the_pair)插入它但我无法将其编译(获取:no matching member function for call to 'insert')。

修改
程序看起来像这个:

ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
    // some processing with line to find (int) x and (int) y 
    if (entries.find(x) == entries.end()) {
        auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
        auto &tmp_m = iter_and_success.first->second;
        tmp_m[y] = 1;
    }
    else {
        unordered_map<int, int> r = entries[x];
        if (r.count(y) == 0)
            entries[x][y] = (int) r.size() + 1;
    }
}

1 个答案:

答案 0 :(得分:3)

我认为最好的办法就是将孩子unordered_map移到父母身上:

entries[x] = std::move(tmp);

这样您就可以避免额外复制tmp

另一种方法是在插入之后填充子地图

 auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
 auto& tmp = iter_and_success.first->second;
 tmp[y] = z;

实际上,如果x碰巧多次出现(如果这是不需要的行为 - 只需检查bool标志并采取相应的行动),您就会将数据附加到子地图。

ifstream ifile(path-to-file);
string line;
unordered_map<int, unordered_map<int, int> > entries;
while (getline(ifile, line)) {
    // some processing with line to find (int) x and (int) y 

    // This will insert a new map only if x wasn't present
    auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});

    // This will be 1 if a new map was inserted
    auto value_to_insert = static_cast<int>(iter_and_success.first->second.size()) + 1;

    // This will do anything only if y wasn't present in sub-map
    iter_and_success.first->second.emplace(y, value_to_insert);
}