Which way to assign values to a map is most efficient? Or are they all optimized to the same code (on most modern compilers)?
// 1) Assignment using array index notation
Foo["Bar"] = 12345;
// 2) Assignment using member function insert() and STL pair
Foo.insert(std::pair<string,int>("Bar", 12345));
// 3) Assignment using member function insert() and "value_type()"
Foo.insert(map<string,int>::value_type("Bar", 12345));
// 4) Assignment using member function insert() and "make_pair()"
Foo.insert(std::make_pair("Bar", 12345));
(I know I could benchmark and check compiler output, but this question arose now and the only thing I have close at hand is my mobile phone... hehe)
put() method of HashMap is used to insert a mapping into a map. This means we can insert a specific key and the value it is mapping to into a particular map. If an existing key is passed then the previous value gets replaced by the new value. If a new pair is passed, then the pair gets inserted as a whole.
map insert() in C++ STL. The map::insert() is a built-in function in C++ STL which is used to insert elements with a particular key in the map container. Parameters: The function accepts a pair that consists of a key and element which is to be inserted into the map container.
What exactly do you want to initialize to zero? map's default constructor creates empty map. You may increase map's size only by inserting elements (like m["str1"]=0 or m. insert(std::map<std::string,int>::value_type("str2",0)) ).
Time complexity: k*log(n) where n is size of map, k is no. of elements inserted.
First, there are semantic differences between []
and insert
:
[]
will replace the old value (if any)insert
will ignore the new value (if an old value is already present)therefore comparing the two is useless in general.
Regarding the inserts versions:
std::map<std::string, int>::value_type
is std::pair<std::string const, int>
so no (important) difference between 3 and 4std::make_pair("Bar", 12345)
is cheaper than std::pair<std::string, int>("Bar", 12345)
because the std::string
type is a full fledged class with operations to do on copy and "Bar"
is just a string literal (thus just a pointer copy); however since at the end you do need to create the std::string
... it will depend on the quality of your compilerIn general, I would recommend:
[]
for updatinginsert(std::make_pair())
for ignoring duplicatesstd::make_pair
is not only shorter, it also respects the DRY guideline: Don't Repeat Yourself.
For completeness though, the fastest (and easiest) would be emplace
(C++11 enabled):
map.emplace("Bar", 12345);
Its behavior is that of insert
, but it constructs the new element in-place.
1) may be slightly slower than the other methods because std::map::operator[]
first default-creates the object if it doesn't already exist, then returns a reference that you can use operator=
on to set your desired value, i.e. two operations.
2-4) should be equivalent since map::value_type
is a typedef to std::pair
for the same types, and therefore make_pair
is also equivalent. The compiler should treat these identically.
Also note that performance can be increased further if you need to both check for existence (e.g. to perform special logic depending on whether it exists or not) and then also insert it, by using map::lower_bound
to first get a hint to where the element should be, so map::insert
does not have to search the whole map
again:
// get the iterator to where the key *should* be if it existed:
std::map::iterator hint = mymap.lower_bound(key);
if (hint == mymap.end() || mymap.key_comp()(key, hint->first)) {
// key didn't exist in map
// special logic A here...
// insert at the correct location
mymap.insert(hint, make_pair(key, new_value));
} else {
// key exists in map already
// special logic B here...
// just update value
hint->second = new_value;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With