<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>pivotlake.io</title>
  <subtitle>Browse aymeric&#39;s, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.</subtitle>
  <id>https://aggr.aymericbeaumet.com/sources/pivotlake.io/</id>
  <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/sources/pivotlake.io/"/>
  <link rel="self" type="application/atom+xml" href="https://aggr.aymericbeaumet.com/sources/pivotlake.io/atom.xml"/>
  <updated>2026-10-31T18:38:16+00:00</updated>
  <author>
    <name>aymeric&#39;s</name>
  </author>
  <generator version="2.0.0" uri="https://github.com/aymericbeaumet/aggr">aggr</generator>
  <entry>
    <id>urn:aggr:item:c785b6c4b7dde3fedb84b5ce92cb410ae9da1159</id>
    <title type="text">It&#39;s the memory latency, stupid</title>
    <link rel="alternate" type="text/html" href="https://aggr.aymericbeaumet.com/items/hnrss-org/2026-10-31-it-s-the-memory-latency-stupid/"/>
    <link rel="via" type="text/html" href="https://pivotlake.io/blog/its-the-memory-latency-stupid/"/>
    <published>2026-10-31T18:38:16+00:00</published>
    <updated>2026-10-31T18:38:16+00:00</updated>
    <author>
      <name>ntur1337</name>
    </author>
    <category term="news"/>
    <source>
      <title>Hacker News: Front Page</title>
    </source>
    <summary type="text">Making GROUP BY faster by doing more (CPU!) work When you see your databases CPU at 100%, what is it actually doing? We like to act as though CPUs run code linearly for simplicity&#39;s sake, but in truth CPUs are incredibly complex beasts;…</summary>
    <content type="html">&lt;p&gt;Making GROUP BY faster by doing more (CPU!) work&lt;/p&gt;
&lt;p&gt;When you see your databases CPU at 100%, what is it &lt;em&gt;actually&lt;/em&gt; doing? We like to act as though CPUs run code linearly for simplicity&#39;s sake, but in truth CPUs are incredibly complex beasts; they can potentially do many instructions at once, or sometimes none at all (despite our console showing 100%). Because CPUs can do so many things, one CPU at 100% may be doing much less than another at 100%. A CPU is considered &amp;quot;idle&amp;quot; only if no task (Linux task) needs CPU time; this does not mean the CPU itself is being fully saturated. So why would a CPU not be fully utilized, even if it appears to be at 100%?&lt;/p&gt;
&lt;p&gt;The answer is usually &lt;strong&gt;memory&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Memory accesses are orders of magnitude slower than internal CPU operations. To give a good picture of how much so, a modern CPU might be able to process somewhere in the realm of 4-8 instructions per nanosecond. A memory access to RAM can take somewhere in the realm of 50-100ns. To ease your mathing, that means a modern CPU can do around 400-800 instructions for every &lt;em&gt;one&lt;/em&gt; memory access from RAM.&lt;/p&gt;
&lt;p&gt;CPU&lt;/p&gt;
&lt;p&gt;CPU core 4–8 instr / ns&lt;/p&gt;
&lt;p&gt;L1 cache ~1 ns&lt;/p&gt;
&lt;p&gt;~64 KB · ~4–8 instructions per access&lt;/p&gt;
&lt;p&gt;L2 cache ~3–4 ns&lt;/p&gt;
&lt;p&gt;~1 MB · ~15–30 instructions per access&lt;/p&gt;
&lt;p&gt;L3 cache ~10–15 ns&lt;/p&gt;
&lt;p&gt;up to a few hundred MB · ~50–100 instructions per access&lt;/p&gt;
&lt;p&gt;DRAM ~50–100 ns&lt;/p&gt;
&lt;p&gt;GBs · ~400–800 instructions per access&lt;/p&gt;
&lt;p&gt;Given this, CPUs are built from the ground up to work their way around this. The most obvious way this is dealt with is CPU caches. CPU caches keep memory closer to the CPU than RAM, literally baked into the CPU chip. The closest cache (the L1 cache) takes around 1ns per memory operation- that&#39;s 50-100x faster than RAM! The &amp;quot;problem&amp;quot; here of course is that the CPU caches are fairly small; the L1 cache for a modern CPU is probably around ~64KB, while the farther caches max out at a few hundred MB for top end processors. A good database tries manipulating data in small &amp;quot;chunks&amp;quot; to take full advantage of caches, and you&#39;ll often hear cache utilization as being one of the top concerns of performance engineering.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at GROUP BY aggregations to get a better grip on cache utilization. In GROUP BY, we&#39;re looking to take a dataset, group it by a certain column (or more), and perform certain aggregations (for example, count, or sum on another column). The &amp;quot;naive&amp;quot; method might be to open a HashTable keyed by the group key that grows ever larger. For every new row, you would check if that key exists- if it does, go to it&#39;s corresponding aggregation and update the result. Simple, right? The problem is that if you have millions of unique groups, you&#39;re not utilizing your cache at all! Nearly every HashTable access will be a &amp;quot;cold&amp;quot; hit that goes to RAM. This means that although your CPU may /look/ like it&#39;s 100% utilized, in truth it&#39;ll constantly be waiting for cold memory accesses.&lt;/p&gt;
&lt;p&gt;To demonstrate this, we&#39;ll take our state-of-the-art Pivot engine and ravage it! We&#39;ll remove all our complex logic and replace it with simplicity:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;consume&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;self&lt;/span&gt;,
    &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; RecordBatch,
    &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;_sender&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; dyn &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Sender&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;RecordBatch&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;unary&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; group_keys &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; batch.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.key_column&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;as_primitive&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;Int64Type&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-control syntax-rust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;key &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;in&lt;/span&gt; group_keys.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-rust&quot;&gt;//&lt;/span&gt; If the Group Key doesn&amp;#39;t exist- set it to 0
&lt;/span&gt;        &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-rust&quot;&gt;//&lt;/span&gt; Afterwards, add 1 to the group- this will give us a count(*) GROUP BY key_column
&lt;/span&gt;        &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.counts.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;or_insert&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&#39;ll then run a simple query &lt;code&gt;SELECT count(*), UserID FROM hits GROUP BY UserID&lt;/code&gt; on the &amp;quot;hits&amp;quot; dataset ClickBench provides (99m rows). This query will give us a count per &lt;code&gt;UserID&lt;/code&gt;, meaning we&#39;ll have an entry in our HashMap per &lt;code&gt;UserID&lt;/code&gt;- I&#39;ll give a spoiler here that there are ~17m unique &lt;code&gt;UserID&lt;/code&gt;.&lt;br /&gt;
Our performance checks will be on a bare metal server from our good friends over at CherryServers (AMD EPYC 9124 Genoa, 16 cores, 128 GB DDR5). We unfortunately can&#39;t use a common AWS/GCP machine because we want access to counters that aren&#39;t exposed there for security reasons (for example, we want to see how much memory is passing from DRAM controller to us). We&#39;ll confine ourselves to a single core, since this naive group by can&#39;t run on many cores.&lt;/p&gt;
&lt;p&gt;To run it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;cat&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell&quot;&gt;&amp;gt;&lt;/span&gt; config.yaml &lt;span class=&quot;syntax-string syntax-unquoted syntax-heredoc syntax-shell&quot;&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-assignment syntax-redirection syntax-shell&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-control syntax-heredoc-token syntax-shell&quot;&gt;EOF&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-string syntax-unquoted syntax-heredoc syntax-shell&quot;&gt;
server:
  bind: 127.0.0.1:5440
workers: 1
datastores:
  default:
    kind: pivotlake
    location: ./data
    default: true
users:
  pivot:
    auth:
      method: trust
&lt;span class=&quot;syntax-keyword syntax-control syntax-heredoc-token syntax-shell&quot;&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;taskset&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; 3 pivot server&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; --&lt;/span&gt;config&lt;/span&gt; config.yaml&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-logical syntax-job syntax-shell&quot;&gt;&amp;amp;&lt;/span&gt;
&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;taskset&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; 7 psql&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;h&lt;/span&gt; 127.0.0.1&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;p&lt;/span&gt; 5440&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;U&lt;/span&gt; pivot&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;\timing on&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This takes... a whopping 3.9 seconds. Is that good? Is that bad? Everything in this world is relative, or so they say. If we run the query again (without restarting the server), it takes 3.6s. The second run is the one we&#39;re more interested in- there&#39;s no disk involved as everything is already sitting in our page-cache.&lt;/p&gt;
&lt;p&gt;You&#39;ll notice we did &lt;code&gt;taskset -c&lt;/code&gt;. This pins the process to a given CPU; this will allow us to run &lt;code&gt;perf stat&lt;/code&gt; on that CPU and see what&#39;s going on internally. We&#39;ll measure two metric groups- percentage of CPU slots stalling because of memory (and not doing anything in the meanwhile), and percentage of CPU slots actually retiring a micro-op:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; perf stat&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;C&lt;/span&gt; 3&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;M&lt;/span&gt; backend_bound_memory,retiring&lt;span class=&quot;syntax-keyword syntax-operator syntax-end-of-options syntax-shell&quot;&gt; --&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; taskset -c 7 psql -h 127.0.0.1 -p 5440 -U pivot -c &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and we get back this&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;Performance counter stats for &amp;#39;CPU(s) 3&amp;#39;:

        8364109137      ex_no_retire.load_not_complete   #     50.1 %  backend_bound_memory
       38233214040      de_no_dispatch_per_slot.backend_stalls
        8977647849      ex_no_retire.not_complete
       11861387798      ls_not_halted_cyc
       11431618219      ex_ret_ops                       #     16.1 %  retiring
       11858248045      ls_not_halted_cyc

       4.030148989 seconds time elapsed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells us that 50.1% of the time, the CPU couldn&#39;t do anything because it was stalling on memory! And only 16.1% of the time the CPU was actually retiring (aka doing) operations.&lt;/p&gt;
&lt;p&gt;Another interesting stat to get is how many of our CPU memory loads are coming from DRAM (and not from caches):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; perf stat&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;C&lt;/span&gt; 3&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt;   -&lt;/span&gt;e&lt;/span&gt; ls_dmnd_fills_from_sys.dram_io_near&lt;span class=&quot;syntax-keyword syntax-operator syntax-end-of-options syntax-shell&quot;&gt;   --&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; taskset -c 7 psql -h 127.0.0.1 -p 5440 -U pivot -c &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt; Performance counter stats for &amp;#39;CPU(s) 3&amp;#39;:

          76190837      ls_dmnd_fills_from_sys.dram_io_near

       3.996301634 seconds time elapsed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every load is 64 bytes (the minimum amount you can bring, a cache line), so we can multiply by 64 to see we pulled 4.5GB during this query from DRAM on CPU loads (this is without any prefetching).&lt;/p&gt;
&lt;p&gt;Let&#39;s now try to improve our algorithm to take advantage of the CPU caches. To do this, we&#39;ll use a method called radix partitioning. The idea is to split the merge into two distinct phases:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 1:&lt;/strong&gt; In this phase, we&#39;re simply going to separate the keys into 4096 different partitions (simply a Vec of SlabVecs- a SlabVec is a data structure similar to a Vec that is above memory that is already paged in. We don&#39;t use Vecs for raw memory in Pivot because it creates a lot of variance; not something for this blog post!). The partition will be decided by hashing the key and taking it&#39;s top 12 bits (2**12=4096).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;consume&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;self&lt;/span&gt;,
    &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; RecordBatch,
    &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;_sender&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; dyn &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Sender&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;RecordBatch&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;unary&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; keys &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; batch.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;column&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.key_column&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;as_primitive&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;Int64Type&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-control syntax-rust&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;key &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;in&lt;/span&gt; keys.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; hash &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.hasher.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;hash_one&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-rust&quot;&gt;//&lt;/span&gt; Since we want top 12 bits, we shift the hash (a u64) 52 bits to the right
&lt;/span&gt;        &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; partition &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;hash &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;52&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.partitions&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;[&lt;/span&gt;partition&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;]&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.allocator&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; key&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UserID&lt;/th&gt;
&lt;th&gt;hash(UserID)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;002&lt;/strong&gt;A91F3…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;000&lt;/strong&gt;7C4E2…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;FFF&lt;/strong&gt;3B05D…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;002&lt;/strong&gt;A91F3…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;001&lt;/strong&gt;D6A88…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;42&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;000&lt;/strong&gt;7C4E2…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;002&lt;/strong&gt;E17B4…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0x&lt;strong&gt;002&lt;/strong&gt;A91F3…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;partition = &lt;code&gt;hash &amp;gt;&amp;gt; 52&lt;/code&gt;, the first 3 hex digits&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Partition 0&lt;/strong&gt; 0x000000… –&lt;br /&gt;
0x000FFF…&lt;/p&gt;
&lt;p&gt;42 42&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Partition 1&lt;/strong&gt; 0x001000… –&lt;br /&gt;
0x001FFF…&lt;/p&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Partition 2&lt;/strong&gt; 0x002000… –&lt;br /&gt;
0x002FFF…&lt;/p&gt;
&lt;p&gt;7 7 99 7&lt;/p&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Partition 4095&lt;/strong&gt; 0xFFF000… –&lt;br /&gt;
0xFFFFFF…&lt;/p&gt;
&lt;p&gt;13&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 2:&lt;/strong&gt; When all data has come through, go partition by partition, each time creating a HashMap, aggregating the partition into it, and then outputting it. This phase is very similar to our original algorithm, but we&#39;re going to use the hash from phase 1.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Rust&quot;&gt;&lt;span class=&quot;syntax-source syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-function syntax-rust&quot;&gt;fn&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-entity syntax-name syntax-function syntax-rust&quot;&gt;into_outputter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;self&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-return-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;unary&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Result&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;Option&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;Self&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Outputter&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; groups &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;syntax-keyword syntax-control syntax-rust&quot;&gt;for&lt;/span&gt; rows &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-language syntax-rust&quot;&gt;self&lt;/span&gt;.partitions &lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; table&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-generic syntax-rust&quot;&gt;HashTable&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-begin syntax-rust&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;u64&lt;/span&gt;, &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;i64&lt;/span&gt;, &lt;span class=&quot;syntax-storage syntax-type syntax-rust&quot;&gt;u64&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-generic syntax-end syntax-rust&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;HashTable&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;syntax-comment syntax-line syntax-double-slash syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-comment syntax-rust&quot;&gt;//&lt;/span&gt; (hash, key, count)
&lt;/span&gt;        rows.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;for_each&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;key&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;syntax-keyword syntax-control syntax-rust&quot;&gt;match&lt;/span&gt; table.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;group.&lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; key&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;group.&lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;Entry&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Occupied&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-storage syntax-modifier syntax-rust&quot;&gt;mut&lt;/span&gt; group&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&amp;gt;&lt;/span&gt; group.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;get_mut&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;Entry&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;Vacant&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;syntax-keyword syntax-operator syntax-rust&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-begin syntax-rust&quot;&gt;{&lt;/span&gt; slot.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-rust&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
            &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
        groups.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;table.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;into_iter&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;span class=&quot;syntax-support syntax-function syntax-rust&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-parameters syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;_&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;syntax-variable syntax-parameter syntax-rust&quot;&gt;count&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-parameters syntax-end syntax-rust&quot;&gt;|&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function syntax-closure syntax-rust&quot;&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;syntax-punctuation syntax-separator syntax-rust&quot;&gt;,&lt;/span&gt; count&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-punctuation syntax-terminator syntax-rust&quot;&gt;;&lt;/span&gt;
    &lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-support syntax-type syntax-rust&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-path syntax-rust&quot;&gt;Outputter&lt;span class=&quot;syntax-punctuation syntax-accessor syntax-rust&quot;&gt;::&lt;/span&gt;&lt;/span&gt;new&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-begin syntax-rust&quot;&gt;(&lt;/span&gt;groups&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-group syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-group syntax-end syntax-rust&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-block syntax-rust&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-section syntax-block syntax-end syntax-rust&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Partitions, one at a time&lt;/p&gt;
&lt;p&gt;0–1 done 2 in progress 3–4095 waiting&lt;/p&gt;
&lt;p&gt;Partition 2&lt;/p&gt;
&lt;p&gt;HashTable&lt;/p&gt;
&lt;p&gt;Output&lt;/p&gt;
&lt;p&gt;7 7 99 7&lt;/p&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;UserID count&lt;/p&gt;
&lt;p&gt;7 3&lt;/p&gt;
&lt;p&gt;99 1&lt;/p&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;(UserID, count)&lt;/p&gt;
&lt;p&gt;(7, 3)&lt;/p&gt;
&lt;p&gt;(99, 1)&lt;/p&gt;
&lt;p&gt;At first glance, this solution may seem rather odd. We&#39;re doing &lt;strong&gt;more&lt;/strong&gt; operations here, not less! Every row, in both solutions, is hashed and sent into a HashMap. But in this solution, we&#39;re first pushing rows into seemingly meaningless vecs.&lt;/p&gt;
&lt;p&gt;The key here (no pun intended) is to understand why we&#39;ve done this; it&#39;s to make the aggregating HashMaps &lt;strong&gt;smaller&lt;/strong&gt;. By dividing our group by into 4096 pieces, we&#39;ve made our working HashMaps much likelier to fit into our CPU caches. Every time we do a lookup on our HashMap, our CPU is more likely to find the relevant memory sitting in it&#39;s caches, which saves a big chunk of time. But why trust me? Let&#39;s run it!&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;taskset&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; 7 psql&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;h&lt;/span&gt; 127.0.0.1&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;p&lt;/span&gt; 5440&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;U&lt;/span&gt; pivot&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-single syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;\timing on&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;c&lt;/span&gt; &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And... Boom! 3.3 seconds, and then on second run 2.7 seconds! We&#39;ve definitely made an improvement. But to really drive this point home, let&#39;s run perf again:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; perf stat&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;C&lt;/span&gt; 3&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;M&lt;/span&gt; backend_bound_memory,retiring&lt;span class=&quot;syntax-keyword syntax-operator syntax-end-of-options syntax-shell&quot;&gt; --&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; taskset -c 7 psql -h 127.0.0.1 -p 5440 -U pivot -c &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And our results:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt; Performance counter stats for &amp;#39;CPU(s) 3&amp;#39;:

        3790955223      ex_no_retire.load_not_complete   #     23.5 %  backend_bound_memory
       20376118172      de_no_dispatch_per_slot.backend_stalls
        5442424751      ex_no_retire.not_complete
       10083617764      ls_not_halted_cyc
       19350459182      ex_ret_ops                       #     32.2 %  retiring
       10023435553      ls_not_halted_cyc

       3.575992317 seconds time elapsed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can see the picture has completely changed- 23.5% of the time is spent on waiting for memory (as opposed to 50% before), 32% for actually retiring operations. You may notice we&#39;re actually doing &lt;strong&gt;more&lt;/strong&gt; work, not less- in this run, we did 19350459182 operations (the &lt;code&gt;ex_ret_ops&lt;/code&gt; counter), whereas before the database did 11431618219 operations. This is worth it though, because as we said before- if we can translate cold DRAM accesses into CPU instructions, it&#39;s nearly always a good trade to make. In this case, we went down from 8364109137 CPU slots stalled because of memory to 3790955223.&lt;/p&gt;
&lt;p&gt;To complete the picture and really see we&#39;re pulling less memory from the DRAM, let&#39;s again check how many our memory loads come from DRAM:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;code-snippet&quot; data-language=&quot;Shell&quot;&gt;&lt;span class=&quot;syntax-source syntax-shell syntax-bash&quot;&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-shell&quot;&gt;&lt;span class=&quot;syntax-variable syntax-function syntax-shell&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; perf stat&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt; -&lt;/span&gt;C&lt;/span&gt; 3&lt;span class=&quot;syntax-variable syntax-parameter syntax-option syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-parameter syntax-shell&quot;&gt;   -&lt;/span&gt;e&lt;/span&gt; ls_dmnd_fills_from_sys.dram_io_near&lt;span class=&quot;syntax-keyword syntax-operator syntax-end-of-options syntax-shell&quot;&gt;   --&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;syntax-meta syntax-function-call syntax-arguments syntax-shell&quot;&gt; taskset -c 7 psql -h 127.0.0.1 -p 5440 -U pivot -c &lt;span class=&quot;syntax-string syntax-quoted syntax-double syntax-shell&quot;&gt;&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-begin syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;SELECT count(*) FROM (SELECT COUNT(*), UserID FROM hits GROUP BY UserID)&lt;span class=&quot;syntax-punctuation syntax-definition syntax-string syntax-end syntax-shell&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt; Performance counter stats for &amp;#39;CPU(s) 3&amp;#39;:

          25688280      ls_dmnd_fills_from_sys.dram_io_near

       3.009547012 seconds time elapsed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whoo! That means that on demand we pulled 1.5GB from DRAM, instead of 4.5GB in the naive version.&lt;/p&gt;
&lt;p&gt;That, of course, isn&#39;t the limit of how much we can utilize our CPU cache for GROUP BYs. And utilizing our CPU cache isn&#39;t the only way we can &amp;quot;hide&amp;quot; DRAM latency; another trick is prefetching memory to our cache before we need it, and yet another trick is creating algorithms that allow maximization of memory throughput- but that&#39;s not for this blog! We&#39;ll go into that in our next blog where we look at our /seemingly very weird/ implementation of JOIN probing.&lt;/p&gt;
&lt;p&gt;For now, without explaining too much, I&#39;ll leave you with Pivot&#39;s speed for this query on a single core:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;Time: 1848.353 ms (00:01.848)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the amount of RAM we bring:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt; Performance counter stats for &amp;#39;CPU(s) 3&amp;#39;:

          14917958      ls_dmnd_fills_from_sys.dram_io_near

       2.182674864 seconds time elapsed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which comes out to 954 MB.&lt;/p&gt;
&lt;p&gt;Of course, Pivot knows to run in parallel on our 16 cores (where there are many other interesting cases), in which case it comes out to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;code-snippet&quot;&gt;Time: 171.773 ms
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nice :)&lt;/p&gt;
&lt;p&gt;Try out Pivot if you want to have super speeds above parquets (OSS fun!), see you next time.&lt;/p&gt;
</content>
  </entry>
</feed>
