atomicmap

package module
v0.0.0-...-96a7f1f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2021 License: CC0-1.0 Imports: 11 Imported by: 8

README

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:

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	NotFound        = errors.NotFound
	NoSpaceLeft     = errors.NoSpaceLeft
	NotImplemented  = errors.NotImplemented
	AlreadyGrowing  = errors.AlreadyGrowing
	ForbiddenToGrow = errors.ForbiddenToGrow
	ConditionFailed = errors.ConditionFailed
)

Functions

This section is empty.

Types

type ConditionFunc

type ConditionFunc func(value interface{}) bool

type Key

type Key = I.Key

type Map

type Map = *openAddressGrowingMap

func New

func New() Map

func NewWithArgs

func NewWithArgs(blockSize uint64) Map

blockSize should be a power of 2 and should be greater than the maximal amount of elements you're planning to store. Keep in mind: the higher blockSize you'll set the longer initialization will be (and more memory will be consumed).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL