Closed Manoj-red-hat closed 3 years ago
Running your example with the latest (1.74) Boost version shows that when the number of elements passes a limit, the data structure does not fit in cache and the reallocations/copies start doing a lot of harm. flatmap is NOT a hashtable, it's an ordered sequence, so this is not really a bug, but expected behaviour explained in [flat(multi)map/set associative containers](https://www.boost.org/doc/libs/1_58_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx).
flat_map has slow insertions because it needs to insert the new element and move the rest. This means that this initialization complexity is quadratic,.
To improve this, you can first copy all data to the sequence_type and the adopt it, which makes the insertion really fast:
#include <fstream>
#include <string>
#include <boost/container/flat_map.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/version.hpp>
#include <iostream>
template<class V>
void readFileToSequence(std::string file, V *col, int scale) {
std::ifstream myfile(file);
for (std::string line; getline(myfile, line);) {
int i = std::stoi(line);
col->push_back({i, i});
}
}
int main(){
std::cout << "Using Boost "
<< BOOST_VERSION / 100000 << "." // major version
<< BOOST_VERSION / 100 % 1000 << "." // minor version
<< BOOST_VERSION % 100 // patch level
<< std::endl;
typedef boost::container::flat_map<int, int> flat_map_t;
flat_map_t flatMap;
typename flat_map_t::sequence_type data;
std::cout<<"Data read initiated"<<std::endl;
readFileToSequence("./data.txt", &data, 0);
std::cout<<"flatMap will adopt the sequence"<<std::endl;
flatMap.adopt_sequence(boost::move(data));
std::cout << "Finished! Size:" << flatMap.size() << '\n';
}
which prints:
Using Boost 1.74.0 Data read initiated flatMap will adopt the sequence Finished! Size:9101943
Compile :
Output:
Data File Compressed data file
gdb