Re: Swiss table implementation

Martin McClure <[email protected]> Wed, 27 Aug 2025 22:16:24 -0700
Newsgroups gmane.comp.lang.smalltalk.vwnc
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------C2JIbtXq2XrgiPgTR4dHoN07
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Hi Holger,

Interesting -- I hadn't seen Swiss tables.

In my experience, the most important factor in how hash table lookup=20
performs is the number of cache line reads it takes, on average, to find=20
an entry. With a modern hardware cache line read taking a couple of=20
orders of magnitude more time than executing an instruction, what and=20
how many instructions you use is less of a factor. With open-addressing=20
linear-probing tables like Smalltalk has used for decades, if your hash=20
function is decent and you don't load the table beyond 70%-80%, most=20
lookups can be done in one cache line read, and very few take more than=20
two cache line reads.

It doesn't look like Swiss tables improve much on this. Even if you=20
store each metadata word in the same cache line as the data word, you=20
still have to read one cache line, and sometimes more. It's possible=20
that the Swiss table tolerates mediocre hash functions better, or might=20
save memory by allowing higher loading with similar speed. It's also=20
possible that its insert/delete performance is better -- most of my=20
experience has been with tables that have far more lookups than changes.

So my first guess (and with performance one does need to test to be=20
sure) is that Swiss tables would give little to no speed advantage in=20
Smalltalk. over the open-addressing linear probing tables of the kind=20
that Smalltalk as used for decades. I'm not sure what was wrong with=20
Go's and C++'s older map implementations, but that's something that a=20
lot of people get wrong. Even getting a hash table design /almost/ right=20
has a penalty.

But I'd also be interested in seeing the results if someone were to try it.

Regards,

-Martin

On 8/27/25 2:40 AM, Holger Kleinsorgen wrote:
> Hello,
>
> has anyone tried to implement a Swiss table dictionary (see=20
> https://urldefense.com/v3/__https://go.dev/blog/swisstable__;!!DZ3fjg!8Z3=
XGyBHxwt6G4_jYTjFhcxayB-6TsB0CINXIN_LZ9-cwX1VQJ9CfnfLCLqqNsUR7A9USTatcELwUa=
_hoASvX-pQJBL0UIjQuA$ =20
> <https://urldefense.com/v3/__https://go.dev/blog/swisstable__;!!DZ3fjg!6z=
k_LKh2X8Ni0_GbEirgVYVib_zPSOY6PUzEdmsv4uYFAT00VkL04_e6a44V8wAy7_8QaSoHNpF8Q=
sbyTjeiF_LdirjWMBbwfaPpTQ$>)=20
> in Smalltalk? I'm curious if there is a performance benefit without=20
> SIMD instructions.
>
> Holger
>=

--------------C2JIbtXq2XrgiPgTR4dHoN07
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Holger,</p>
    <p>Interesting -- I hadn't seen Swiss tables.</p>
    <p>In my experience, the most important factor in how hash table
      lookup performs is the number of cache line reads it takes, on
      average, to find an entry. With a modern hardware cache line read
      taking a couple of orders of magnitude more time than executing an
      instruction, what and how many instructions you use is less of a
      factor. With open-addressing linear-probing tables like Smalltalk
      has used for decades, if your hash function is decent and you
      don't load the table beyond 70%-80%, most lookups can be done in
      one cache line read, and very few take more than two cache line
      reads.</p>
    <p>It doesn't look like Swiss tables improve much on this. Even if
      you store each metadata word in the same cache line as the data
      word, you still have to read one cache line, and sometimes more.
      It's possible that the Swiss table tolerates mediocre hash
      functions better, or might save memory by allowing higher loading
      with similar speed. It's also possible that its insert/delete
      performance is better -- most of my experience has been with
      tables that have far more lookups than changes.<br>
    </p>
    <p>So my first guess (and with performance one does need to test to
      be sure) is that Swiss tables would give little to no speed
      advantage in Smalltalk. over the open-addressing linear probing
      tables of the kind that Smalltalk as used for decades. I'm not
      sure what was wrong with Go's and C++'s older map implementations,
      but that's something that a lot of people get wrong. Even getting
      a hash table design <i>almost</i> right has a penalty.</p>
    <p>But I'd also be interested in seeing the results if someone were
      to try it.</p>
    <p>Regards,</p>
    <p>-Martin<br>
    </p>
    <div class="moz-cite-prefix">On 8/27/25 2:40 AM, Holger Kleinsorgen
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAGhifExbD6LLP_rS+H=f1NxPVfzZqsnQVCaSSEqCSz++qtqG_w@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div>Hello,</div>
        <div><br>
        </div>
        <div>has anyone tried to implement a Swiss table dictionary
          (seeĀ <a
href="https://urldefense.com/v3/__https://go.dev/blog/swisstable__;!!DZ3fjg!6zk_LKh2X8Ni0_GbEirgVYVib_zPSOY6PUzEdmsv4uYFAT00VkL04_e6a44V8wAy7_8QaSoHNpF8QsbyTjeiF_LdirjWMBbwfaPpTQ$"
            moz-do-not-send="true">https://go.dev/blog/swisstable</a>)
          in Smalltalk? I'm curious if there is a performance benefit
          without SIMD instructions.</div>
        <div><br>
        </div>
        <div>Holger</div>
        <div><br>
        </div>
      </div>
    </blockquote>
  </body>
</html>

--------------C2JIbtXq2XrgiPgTR4dHoN07--