Graph Engine vs. C++ unordered_map: memory consumption test, Part 2
blogs.msdn.com
blogs.msdn.com
In any code base where performance matters, most important use cases for unordered_map would be replaced with a purpose-built implementation (like with GraphEngine). Not only is it pretty trivial to design and implement custom maps for various use cases, you can usually ensure at least a 2X improvement across all relevant metrics relative to the standard library unordered_map.
Based on the relative metrics for GraphEngine and C++ unordered_map in this article, I would expect a purpose-built C++ implementation to be significantly faster than GraphEngine. I know that is not what is being measured but it in real-world C++ implementations, it is how most properly engineered architectures would do it.
Jo Muñoz wrote a cool blog series on the current implementations in circulation, the flaws with the interface, and how his implementation (Boost multi_index) made further optimisations despite the constraints.
Don't miss the other two parts of the series - look under October on the right. He did extensive bookmarks in November as well.
http://bannalia.blogspot.co.uk/2013/10/implementation-of-c-u...
Thank you also for maintaining your GCC distro for Windows[0] and the the many great presentations you have given at CppCon, Channel 9, Going Native etc.
vector<int> v = {1,2,3,4,5};
cout << accumulate(begin(v), end(v), 1, multiplies<>());Is it possible to use VIsual C++'s STL inside of Linux?
(Of course, you would want to do as well as possible within the given bounds.)
http://bannalia.blogspot.com/2014/01/a-better-hash-table.htm... http://bannalia.blogspot.com/2014/01/a-better-hash-table-gcc... http://bannalia.blogspot.com/2014/01/a-better-hash-table-cla...
... which has been a trivial wrapper around HeapAlloc for a long time, and the HeapAlloc implementation varies by the Windows version. In particular, Vista+ versions are low-fragmentation heaps and W7+ versions have an outstanding multi-threaded performance.
In other words, deferring to a "MSVC's built-in memory allocator" doesn't make much sense.
(In 2015, we're introducing a little bit of extra trickery though. In std::allocator, we'll highly align large allocations to be friendly to autovectorization. This isn't done at the lower malloc/new levels because they don't get size information at deallocation time, but the std::allocator interface has always required that information even if it was previously ignored. IIRC this buys 15% or so, which makes the back-end devs drool. Our current magic number for "large" is 4 KB, so this basically never affects node-based containers, only stuff like big vectors.)
Ok this and other things you posted here are mighty interesting - do you (or someone else working on this) have (has) a blog where news like this gets announced?
[1] http://www.drdobbs.com/cpp/improving-performance-with-custom... [2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n227... [3] http://locklessinc.com/benchmarks_allocator.shtml
start_time = std::chrono::steady_clock::now();
for (auto entry : param_entries)
{
void* cell_buf = new char[entry.cell_size];
auto upsert_result = LocalStorage.emplace(entry.cell_id, CellEntry{ cell_buf, entry.cell_size, 0 });
if (!upsert_result.second)
{
std::swap(cell_buf, upsert_result.first->second.ptr);
delete[] cell_buf;
}
if (rand() % 3 == 0)
{
delete[] upsert_result.first->second.ptr;
LocalStorage.erase(entry.cell_id);
}
}
end_time = std::chrono::steady_clock::now();
He's not testing unordered_map performance alone, but the performance of new/delete & unordered_map. Also entry is a copy of param_entries's item, it should be changed to auto& entry. So he's essentially copying the whole array while iterating.