Reputation: 3688
I am writing a C++ program, to read from a big file line by line, and insert each line-info (after some processing) to an unordered_map.
This is the declaration of the unordered_map:
unordered_map<int, unordered_map<int, int> > entries;
What I did to insert was (this is in the loop code-block in which I process each line of the text file):
unordered_map<int, int> tmp;
tmp[y] = z;
entries[x] = tmp;
But this proved to behave badly in performance terms.
I've tried creating a pair<int, pair<int, int>>
and inserting it using entries.insert(the_pair)
but I cannot get this to compile (getting: no matching member function for call to 'insert'
).
Edit:
The program looks like this:
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;
}
}
Upvotes: 1
Views: 87
Reputation: 3977
I think your best bet is simply move the child unordered_map
to the parent one:
entries[x] = std::move(tmp);
This way you will avoid an extra copy of tmp
.
Another way is to fill up the child map after inserting it.
auto iter_and_success = entries.emplace(x, unordered_map<int, int>{});
auto& tmp = iter_and_success.first->second;
tmp[y] = z;
This way actually, you will append the data to the child map if x
happens to occur multiple times (if this is unwanted behavior - just check the bool flag and act accordingly).
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);
}
Upvotes: 3