c++ - 如何(有效地)插入以 map 为值的 map ?

标签 c++ performance insert unordered-map

我正在编写一个 C++ 程序,逐行读取一个大文件,并将每一行信息(经过一些处理后)插入到一个 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;
    }
}

最佳答案

我认为最好的办法就是将子 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);
}

关于c++ - 如何(有效地)插入以 map 为值的 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33065574/

相关文章:

c++ - 初始化头文件中的引用 C++

c++ - 用于创建库的 header 是否必须与使用库的 header 相同

Mysql select * from tables where primary_key in (1,2,,...) 很慢

sql - 使用数据库变量时查询性能低下

C程序无法识别空指针

php - Select id_value from db into array 复选框并将多个值从数组复选框插入到一列,并以逗号分隔

c++ - 使用MSVC 2017编译器在Qt Creator中进行调试

c++ - 在QTreeWidget中排序时的调试断言(无效的比较器)

java - 计算吞吐量

java - YouTube 插入错误凭据