<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    
    <title>Martin Leitner-Ankerl</title>
    
    
    <description>This website is a virtual proof that I'm awesome</description>
    
    <link>http://martin.ankerl.com/</link>
    <atom:link href="http://martin.ankerl.com/feed.xml" rel="self" type="application/rss+xml" />
    
    
      <item>
        <title>Comprehensive C++ Hashmap Benchmarks 2022</title>
        <description>
          Where I've spent way too much time creating benchmarks of C++ hashmaps - 
          It’s been over 3 years since I’ve spent considerable time finding the best C++ hashmap. After several requests I finally gave in and redid the benchmark with state of C++ hashmaps as of August 2022. This took much more work than I initially anticipated, mostly due to the fact that benchmarks take a looong time, and writing everything up and creating a representation that is actually useful takes even more time. Thanks everyone who annoyingly kept asking me for updates :wink: TL;DR: Here are the benchmark results! Table of Contents Benchmark Infrastructure Hardware Software Benchmarks Stable References Modifying Numbers Benchmarks...
        </description>
        <pubDate>Sat, 27 Aug 2022 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2022/08/27/hashmap-bench-01/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2022/08/27/hashmap-bench-01/</guid>
      </item>
    
      <item>
        <title>Kindle Paperwhite Tips</title>
        <description>
          Some helpful Tricks - 
          I recently upgraded from my 8 year old Kindle Keyboard (2011) to a brand new Kindle Paperwhite (2019, generation 10). So far, it is a great upgrade. Here are some tricks that I found useful: Custom Fonts Connect the kindle with USB, you’ll see a folder fonts. I’ve tried a few fonts, and really like Literata. It’s very similar to Amazon’s Bookerly, and made for e-books. It’s also the font you’ll see in the header for this post. Here’s how to install it: Go to https://fonts.google.com/specimen/Literata Click “Select this font” Click on the new popup Click the download arrow to...
        </description>
        <pubDate>Fri, 23 Aug 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/08/23/kindle-paperwhite-tips/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/08/23/kindle-paperwhite-tips/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Conclusion</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion 👈 In conclusion, I can only say one thing with certainty: there is not one single best hashmap. What’s best for you will depend on your usecase, and I advise you to create a representative benchmark for your use...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-05-conclusion/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-05-conclusion/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Iterating</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating 👈 Conclusion Iteration benchmark works like this: I create a Map&amp;lt;uint64_t, uint64_t&amp;gt;, and each time I insert one random element the whole map is iterated. Once 50k elements are inserted, elements are removed one by one and each time the...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-06-result-IterateIntegers/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-06-result-IterateIntegers/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Find 1 -- 1M std::string</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string 👈 Iterating Conclusion Again much like Find 1-2000 size_t, except that this time we use 13 byte strings. Every time we insert 4 strings, 800 lookups are performed. This is repeated until 1 million entries are inserted. Results Hashes In Insert...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-05-result-RandomFindString_1000000/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-05-result-RandomFindString_1000000/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Find 1 -- 100k std::string</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string 👈 Find 1 – 1M std::string Iterating Conclusion This test is practically exactly the same as Find 1-2000 size_t, except that it uses 100 byte long std::string. There are 4000 lookups every 4 inserts, until 100k entries inserts. Results Hashes In Insert &amp;amp; Erase std::string we...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-04-result-RandomFindString/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-04-result-RandomFindString/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Find 1 -- 500k uint64_t</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t 👈 Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion This benchmark is the same as previous, but with 4000 lookups for every 4 inserts until the map contains 500k elements. Results Hashes Same behavior as for the other benchmarks: robin_hood::hash is fastest, absl::Hash second, and libstdc++-v3 problematic....
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-03-result-RandomFind_500000/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-03-result-RandomFind_500000/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Find 1 -- 2000 uint64_t</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t 👈 Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion In many use cases find performance is probably considered the most important benchmark. This benchmark was tricky to implement, as it should be as unbiased as possible. It tries to do the following: Lookup with different probability of...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-02-result-RandomFind_2000/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-04-02-result-RandomFind_2000/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Insert &amp; Erase std::string</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string 👈 Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion This benchmark is very similar to Insert &amp;amp; Erase, but with a Map&amp;lt;std::string, std::string&amp;gt;. It constantly inserts and removes random strings. The benchmark is run with different sizes of std::string: 7, 8, 13, 100, and 1000 bytes. Each...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-04-result-RandomInsertEraseStrings/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-04-result-RandomInsertEraseStrings/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Insert &amp; Erase uint64_t</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t 👈 Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion The core of the benchmark is this loop: Map&amp;lt;uint64_t, uint64_t&amp;gt; map; for (size_t i = 0; i &amp;lt; 50'000'000; ++i) { map.emplace(rng() &amp;amp; bitMask, i); map.erase(rng() &amp;amp; bitMask); } On first glance it looks similar to the previous...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-03-result-RandomInsertErase/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-03-result-RandomInsertErase/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Insert &amp; Access with Varying Probability int</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int 👈 Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion This benchmark has been adapted from attractivechaos’ Revisiting hash table performance code. It basically contains this main part: Map&amp;lt;int, int&amp;gt; map; for (size_t i = 0; i &amp;lt; 50'000'000; ++i) { checksum += ++map[rng(max_rng)]; } Here rng(max_rng) creates...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-02-result-RandomDistinct2/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-02-result-RandomDistinct2/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Insert &amp; Erase 100M int</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int 👈 Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion Now it gets interesting. This benchmark benchmarks a few things at once: Insert 100 million random int into a Map&amp;lt;int, int&amp;gt;. Clear all entries with clear(). Reinsert 100 million random int into the same cleared map. Remove all...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-01-result-InsertHugeInt/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-03-01-result-InsertHugeInt/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Construction &amp; Insert 1 int &amp; Destruction</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction 👈 Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion Almost the same as Construction &amp;amp; Destruction, but this time a single element is inserted. All maps that do lazy initialization are now forced to actually provide storage memory, and they have to calculate the hash function at...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-02-02-result-CtorDtorSingleEntryMap/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-02-02-result-CtorDtorSingleEntryMap/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Construction &amp; Destruction</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview Construction Benchmarks Construction &amp;amp; Destruction 👈 Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion To get started, the first benchmark is a very simple one: measure how fast the hashmap can be constructed and destructed. Some maps perform some kind of lazy initialization, where data is only allocated when the first element...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-02-01-result-CtorDtorEmptyMap/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-02-01-result-CtorDtorEmptyMap/</guid>
      </item>
    
      <item>
        <title>Hashmaps Benchmarks - Overview</title>
        <description>
          Finding the Fastest, Memory Efficient Hashmap - 
          Table of Contents Overview 👈 Construction Benchmarks Construction &amp;amp; Destruction Construction &amp;amp; Insert 1 int &amp;amp; Destruction Modifying Benchmarks Insert &amp;amp; Erase 100M int Insert &amp;amp; Access with Varying Probability int Insert &amp;amp; Erase uint64_t Insert &amp;amp; Erase std::string Accessing Find 1 – 2000 uint64_t Find 1 – 500k uint64_t Find 1 – 100k std::string Find 1 – 1M std::string Iterating Conclusion I’ve spent a long time developing my robin_hood::unordered_map, and after claiming that it is now the fastest hashmap I understandably got quite a few skeptic comments. Some of the comments were quite right, and my benchmarks were not...
        </description>
        <pubDate>Mon, 01 Apr 2019 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-01-overview/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2019/04/01/hashmap-benchmarks-01-overview/</guid>
      </item>
    
      <item>
        <title>Fast Random bool in C++</title>
        <description>
          With lots of benchmarks - 
          While playing around with fast random number generators, I’ve started contemplating what’s the fastest way to uniformly generate random boolean values. The correct solution is this (never mind the bad seeding of mt19937, but it’s just too cumbersome to do it correctly): std::mt19937 rng(std::random_device{}()); bool rand_bool = std::uniform_int_distribution&amp;lt;&amp;gt;{0, 1}(rng); But is this fast? unfortunately, not so much. It can’t be fast, because each call to the std::uniform_int_distribution&amp;lt;&amp;gt; object has to request a new random number from rng, which means from the 32 random bits that are generated only a single one is used. What a colossal waste. On my quest...
        </description>
        <pubDate>Sat, 08 Dec 2018 00:00:00 +0100</pubDate>
        <link>http://martin.ankerl.com/2018/12/08/fast-random-bool/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2018/12/08/fast-random-bool/</guid>
      </item>
    
      <item>
        <title>Visualizing Bitcoin's Unspent Transaction Output</title>
        <description>
          UTXO in all it's glory - 
          About 5 years ago I’ve created a nice graph of all the bitcoin addresses. I got this: A year later I’ve tried to recreate it, but couldn’t because my PC at that time did not have enough RAM for znort987’s parser that I had used. Fast forward to September 2018, bitcoin now has an a fantastic simple REST interface! So I’ve tried again to create an updated graph of all unspent bitcoin transactions. Unfortunately, my previously used gnuplot script didn’t cut it any more. Too much RAM useage even for my now 32GB machine. I wrote my own renderer and...
        </description>
        <pubDate>Thu, 20 Sep 2018 00:00:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2018/09/20/bitcoin-unspent-transaction-outputs-graph/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2018/09/20/bitcoin-unspent-transaction-outputs-graph/</guid>
      </item>
    
      <item>
        <title>Free Secure Web: Jekyll &amp; Github Pages &amp; Cloudflare</title>
        <description>
          
          I have just finished moving my homepage from WordPress to jekyll + GitHub + Cloudflare. I must say this is really a fantastic setup! I have multiple reasons for that: GitHub Pages are free. Thanks to Cloudflare we get free HTTPS and caching support. Security: WordPress is a constant hassle: my website has been hacked multiple times due to old plugins or not running a recent enough wordpress release. Speed: static websites are fast and practically maintainence free Ease of development: jekyll &amp;amp; git makes development very convenient. From WordPress to Jekyll Unfortunately converting this blog was quite a bit...
        </description>
        <pubDate>Sat, 22 Jul 2017 13:03:00 +0200</pubDate>
        <link>http://martin.ankerl.com/2017/07/22/free-secure-web-jekyll-github-pages-cloudflare/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2017/07/22/free-secure-web-jekyll-github-pages-cloudflare/</guid>
      </item>
    
      <item>
        <title>Ruby to Dot - Graph any Class Hierarchy</title>
        <description>
          
          While cleaning up my blog I have found an old ruby program from 2005: rtd.rb. What this does it it can create pretty graphs from ruby class hierarchy. Interestingly, it still works :smiley: It is quite easy to use, here is a small tutorial: Usage Tutorial Generate graph for the ruby module time. Create a file rtd-time.rb with this content: require &quot;./rtd.rb&quot; stats = RubyToDot.new stats.hide_current_state require 'time' puts stats.generate Now run this command (requires dot, install in Ubuntu with sudo apt install graphviz): ruby rtd-time.rb | dot -Tpng &amp;gt;time.png The generates this graph: This does not yet look very...
        </description>
        <pubDate>Sat, 22 Jul 2017 08:26:58 +0200</pubDate>
        <link>http://martin.ankerl.com/2017/07/22/ruby-to-dot/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2017/07/22/ruby-to-dot/</guid>
      </item>
    
      <item>
        <title>Essential Linux Dev Stuff</title>
        <description>
          
          I’ve recently started developing more in Linux, here is a collection of tools, tips and tricks to get the most out of the box. I’ll expand this list from time to time. Appearance Terminal &amp;amp; Editor font: Hack Here is a test pattern I am using to evaluate fonts: o0O s5S z2Z !|l1Iij {([|})] .,;: ``''&quot;&quot; a@#* vVuUwW &amp;lt;&amp;gt;;^°=-~ öÖüÜäÄßµ \/\/ the quick brown fox jumps over the lazy dog THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 0123456789 &amp;amp;-+@ for (int i=0; i&amp;lt;j; ++i) { } This is how the pattern looks like with Hack, my favourite programming...
        </description>
        <pubDate>Tue, 09 May 2017 08:20:30 +0200</pubDate>
        <link>http://martin.ankerl.com/2017/05/09/essential-linux-dev-stuff/</link>
        <guid isPermaLink="true">http://martin.ankerl.com/2017/05/09/essential-linux-dev-stuff/</guid>
      </item>
    
  </channel>
</rss>
