Skip to content

Commit

Permalink
inline specialized hashing functions and update benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
cornelk committed Aug 29, 2022
1 parent 517efe3 commit e00ce77
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 179 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ Reading from the hash map in a thread-safe way is nearly as fast as reading from
in an unsafe way and twice as fast as Go's `sync.Map`:

```
BenchmarkReadHashMapUint-8 1314156 955.6 ns/op
BenchmarkReadHaxMapUint-8 872134 1316 ns/op (can not handle hash 0 collisions)
BenchmarkReadHashMapUint-8 1601247 754.2 ns/op
BenchmarkReadHaxMapUint-8 1519165 788.3 ns/op
BenchmarkReadGoMapUintUnsafe-8 1560886 762.8 ns/op
BenchmarkReadGoMapUintMutex-8 42284 28232 ns/op
BenchmarkReadGoSyncMapUint-8 468338 2672 ns/op
```

Reading from the map while writes are happening:
```
BenchmarkReadHashMapWithWritesUint-8 890938 1288 ns/op
BenchmarkReadGoMapWithWritesUintMutex-8 14290 86758 ns/op
BenchmarkReadGoSyncMapWithWritesUint-8 374464 3149 ns/op
BenchmarkReadHashMapWithWritesUint-8 1268134 941.6 ns/op
BenchmarkReadHaxMapWithWritesUint-8 1000000 1045 ns/op
BenchmarkReadGoSyncMapWithWritesUint-8 369918 3149 ns/op
```

Write performance without any concurrent reads:
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.19
replace github.com/cornelk/hashmap => ../

require (
github.com/alphadose/haxmap v0.2.1-0.20220828165710-add810974d4f
github.com/cornelk/hashmap v1.0.5-0.20220828215932-152772b42884
github.com/alphadose/haxmap v0.2.2
github.com/cornelk/hashmap v1.0.6-0.20220829041708-517efe3afe16
)

require github.com/cespare/xxhash v1.1.0 // indirect
6 changes: 6 additions & 0 deletions benchmarks/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alphadose/haxmap v0.2.1-0.20220828165710-add810974d4f h1:up6qKu3lIXQ4H3AyJovBy0Tp6Ug++aveneLrUv7TyNo=
github.com/alphadose/haxmap v0.2.1-0.20220828165710-add810974d4f/go.mod h1:Fu37Wlmj7cR++vSLgRTu3fGy8wpjHGmMypM2aclkc1A=
github.com/alphadose/haxmap v0.2.1 h1:ioHHBBj0P/+TmlF1uMOGOB9/3abZWncHEsJCfUC2bC0=
github.com/alphadose/haxmap v0.2.1/go.mod h1:Fu37Wlmj7cR++vSLgRTu3fGy8wpjHGmMypM2aclkc1A=
github.com/alphadose/haxmap v0.2.2-0.20220829041207-9dcd5e601a18 h1:TKxqcdbOHjdE98DTsfiFzCJO3B8nBiDkrC73kK9QXtc=
github.com/alphadose/haxmap v0.2.2-0.20220829041207-9dcd5e601a18/go.mod h1:Fu37Wlmj7cR++vSLgRTu3fGy8wpjHGmMypM2aclkc1A=
github.com/alphadose/haxmap v0.2.2 h1:Dl74rdR4W00rw4qZj4itaEYsVSETn3hh4oMnjbD8AJM=
github.com/alphadose/haxmap v0.2.2/go.mod h1:Fu37Wlmj7cR++vSLgRTu3fGy8wpjHGmMypM2aclkc1A=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
32 changes: 0 additions & 32 deletions hashmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,38 +249,6 @@ func (m *HashMap[Key, Value]) allocate(newSize uintptr) {
}
}

// setDefaultHasher sets the default hasher depending on the key type.
func (m *HashMap[Key, Value]) setDefaultHasher() {
var key Key
switch any(key).(type) {
case string:
m.hasher = m.xxHashString
case int, uint, uintptr:
switch intSizeBytes {
case 2:
m.hasher = m.xxHashWord
case 4:
m.hasher = m.xxHashDword
case 8:
m.hasher = m.xxHashQword
default:
panic(fmt.Errorf("unsupported integer byte size %d", intSizeBytes))
}
case int8, uint8:
m.hasher = m.xxHashByte
case int16, uint16:
m.hasher = m.xxHashWord
case int32, uint32, float32:
m.hasher = m.xxHashDword
case int64, uint64, float64, complex64:
m.hasher = m.xxHashQword
case complex128:
m.hasher = m.xxHashOword
default:
panic(fmt.Errorf("unsupported key type %T", key))
}
}

func (m *HashMap[Key, Value]) isResizeNeeded(store *store[Key, Value], count uintptr) bool {
l := uintptr(len(store.index)) // l can't be 0 as it gets initialized in New()
fillRate := (count * 100) / l
Expand Down
Loading

0 comments on commit e00ce77

Please sign in to comment.