1. 12

    1. 2

      An interesting fact is that Go maps are optimized for certain integer types. Quite a while ago (go 1.13) I did some testing (haven’t done it recently though), and as a result added this comment to one of my codebases:

       // go maps are optimized for only certain int types:
      //  -- results as of go 1.13 on my slow laptop --
      //  BenchmarkInt        297391227    3.99 ns/op
      //  BenchmarkInt8        68107761   17.90 ns/op
      //  BenchmarkInt16       65628482   18.30 ns/op
      //  BenchmarkInt32      292725417    4.08 ns/op
      //  BenchmarkInt64      293602374    4.11 ns/op
      //  BenchmarkUInt       298711089    3.99 ns/op
      //  BenchmarkUInt8       68173198   17.80 ns/op
      //  BenchmarkUInt16      67566312   18.10 ns/op
      //  BenchmarkUInt32     298597942    3.99 ns/op
      //  BenchmarkUInt64     300239860    4.02 ns/op
      // Since we would /want/ to use uint8 here, use uint32 instead
      // Ugly and wasteful, but quite a bit faster for now...
      subtrees map[uint32]*SomeStruct

      Using one of the optimized map key types might improve the benchmarks a bit. So uint16 in the article may be a poor choice, though I doubt it would change the overall outcome (likely still the slowest).

      1. 2

        I thought maps were optimized for 2-byte sized objects as well but I guess that’s not the case. Using a 4-byte key like int32 does make them go faster. Reset becomes a bit slower, but Get and Set see some improvements; I only did a lazy run without a high -count and benchstat, so to get the exact % someone would need to do a couple of extra steps. But if no new map specializations were added, your results are probably still relevant.

    2. 1

      if you were feeling brave, you could use a random sequence number, and skip initializing the memory. (the sparse set it’s replacing can use uninitialized memory)

      1. 1

        For my use case, I wouldn’t mind doing a zeroing even if the language would implicitly do this for me. That array is initialized once and then re-used thousands of times. So I need the get/set/reset operations to be as fast as possible, given the constraints.