Skip to content

A high performance thread-safe implementation of hash map for Golang (accent on high throughput, not at latency)

License

Notifications You must be signed in to change notification settings

xaionaro-go/atomicmap

Repository files navigation

This's a thread-safe implementation of maps without mutex (to be faster) and (IMHO:) works faster than standart golang's non-thread-safe map in the most of cases. This implementation is supposed to be used as a persistent (allocated once and then used forever) high performance map in a highly concurrent program. It supports Get() while Set() without lock if working with different slots (the check if implemented via sync/atomic counters).

Also this map supports mixed key types. For example you can store an element with key "a" and key float64(0.3) in the same map.

More notes:

  • Thread-safety is not implemented for Unset(). It not supposed to be used in a concurrent process.
  • FromSTDMap() is quite stupid-slow and not tested for thread-safety. It not supposed to be used in a concurrent process.
Hash function:

Total collisions on random keys: collisions 66, keyAmount 380 and blockSize 1024:
        66/380/1024 (17.4%)
Total collisions on keys of pessimistic scenario (keys are multiple of blockSize): collisions 63, keyAmount 380 and blockSize 1024:
        63/380/1024 (16.6%)
Total collisions on keys of pessimistic scenario (keys are consecutive): collisions 0, keyAmount 380 and blockSize 1024:
        0/380/1024 (0.0%)

BenchmarkHash_intKeyType_blockSize16-8                  10000000                21.5 ns/op             0 B/op          0 allocs/op
BenchmarkHash_stringKeyType_blockSize16-8                2000000               105 ns/op               0 B/op          0 allocs/op
BenchmarkHash_intKeyType_blockSize1048576-8             10000000                17.0 ns/op             0 B/op          0 allocs/op
BenchmarkHash_stringKeyType_blockSize1048576-8           2000000                98.7 ns/op             0 B/op          0 allocs/op


my hash-map:

Set:
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize16_keyAmount1048576-8                     500000              1076 ns/op             343 B/op          1 allocs/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize16_keyAmount16-8                          500000               297 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize64_keyAmount16-8                         1000000               149 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize128_keyAmount16-8                        1000000               151 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize1024_keyAmount16-8                       1000000               175 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize1024_keyAmount512-8                      1000000               113 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize65536_keyAmount512-8                     1000000               136 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize65536_keyAmount65536-8                   1000000               459 ns/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize4194304_keyAmount1048576-8               1000000               150 ns/op               8 B/op          0 allocs/op
Benchmark_openAddressGrowingMap_Set_intKeyType_blockSize16777216_keyAmount1048576-8              1000000               150 ns/op               8 B/op          0 allocs/op

Get:
Benchmark_openAddressGrowingMap_Get_intKeyType_blockSize1024_keyAmount16-8                       5000000                37.8 ns/op             0 B/op          0 allocs/op
Benchmark_openAddressGrowingMap_Get_intKeyType_blockSize1024_keyAmount512-8                      3000000                47.4 ns/op             0 B/op          0 allocs/op
Benchmark_openAddressGrowingMap_Get_intKeyType_blockSize1024_keyAmount65536-8                    2000000                92.3 ns/op             0 B/op          0 allocs/op
Benchmark_openAddressGrowingMap_Get_intKeyType_blockSize1024_keyAmount1048576-8                  1000000               130 ns/op               0 B/op          0 allocs/op

Unset:
Benchmark_openAddressGrowingMap_Unset_intKeyType_blockSize1024_keyAmount16-8                     5000000                35.5 ns/op
Benchmark_openAddressGrowingMap_Unset_intKeyType_blockSize1024_keyAmount512-8                   20000000                 7.71 ns/op
Benchmark_openAddressGrowingMap_Unset_intKeyType_blockSize1024_keyAmount65536-8                 20000000                 6.72 ns/op
Benchmark_openAddressGrowingMap_Unset_intKeyType_blockSize1024_keyAmount1048576-8               30000000                 6.04 ns/op            0 B/op          0 allocs/op


native map:

Set:
Benchmark_stupidMap_Set_intKeyType_blockSize0_keyAmount16-8                       300000               470 ns/op
Benchmark_stupidMap_Set_intKeyType_blockSize0_keyAmount512-8                      500000               363 ns/op
Benchmark_stupidMap_Set_intKeyType_blockSize0_keyAmount65536-8                    300000               490 ns/op
Benchmark_stupidMap_Set_intKeyType_blockSize0_keyAmount1048576-8                  500000               653 ns/op             170 B/op          1 allocs/op

Get:
Benchmark_stupidMap_Get_intKeyType_blockSize0_keyAmount16-8                      3000000                54.2 ns/op             0 B/op          0 allocs/op
Benchmark_stupidMap_Get_intKeyType_blockSize0_keyAmount512-8                     2000000                61.9 ns/op             0 B/op          0 allocs/op
Benchmark_stupidMap_Get_intKeyType_blockSize0_keyAmount65536-8                   2000000                78.0 ns/op             0 B/op          0 allocs/op
Benchmark_stupidMap_Get_intKeyType_blockSize0_keyAmount1048576-8                 1000000               137 ns/op               0 B/op          0 allocs/op

Unset:
Benchmark_stupidMap_Unset_intKeyType_blockSize0_keyAmount16-8                    3000000                50.0 ns/op
Benchmark_stupidMap_Unset_intKeyType_blockSize0_keyAmount512-8                  20000000                12.3 ns/op
Benchmark_stupidMap_Unset_intKeyType_blockSize0_keyAmount65536-8                20000000                11.1 ns/op
Benchmark_stupidMap_Unset_intKeyType_blockSize0_keyAmount1048576-8              20000000                10.2 ns/op             0 B/op          0 allocs/op

Similar projects:

About

A high performance thread-safe implementation of hash map for Golang (accent on high throughput, not at latency)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages