https://github.com/rsms/go-immutable
Immutable data structures for Go
https://github.com/rsms/go-immutable
Last synced: about 1 year ago
JSON representation
Immutable data structures for Go
- Host: GitHub
- URL: https://github.com/rsms/go-immutable
- Owner: rsms
- License: isc
- Created: 2020-11-24T22:30:08.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-12-01T16:31:31.000Z (over 5 years ago)
- Last Synced: 2025-03-15T21:17:04.919Z (over 1 year ago)
- Language: Go
- Size: 42 KB
- Stars: 35
- Watchers: 3
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Immutable data structures for Go
[][godoc]
[][godoc]
[](https://goreportcard.com/report/github.com/rsms/go-immutable)
[godoc]: https://pkg.go.dev/github.com/rsms/go-immutable
- Based on a immutable persistent Hash Array Mapped Trie (HAMT)
- Minimal interface to the core HAMT implementation so that you can easily
implement your own structures on top of it.
- Comes with some set and map implementations ready to go
- Inspired by Clojure's data structures
- Excellent performance (lookup is about the same as native go maps,
insertion about 20% that of mutable native go maps.)
Example:
```go
package main
import (
"fmt"
"github.com/rsms/go-immutable"
)
m := immutable.EmptyStrMap
m1 := m.Set("Hello", 123)
m2 := m.Set("Hello", 456).Set("Sun", 9)
m3 := m2.Del("Hello")
fmt.Printf("m1: %s\n", m1)
fmt.Printf("m2: %s\n", m2)
fmt.Printf("m3: %s\n", m3)
// Output:
// m1: {"Hello": 123}
// m2: {"Sun": 9, "Hello": 456}
// m3: {"Sun": 9}
```
## Benchmark
```
TEST SAMPLES TIME PER ITERATION
BenchmarkHamtLookup_10 48042776 23.8 ns/op
BenchmarkHamtLookup_100 36947116 31.0 ns/op
BenchmarkHamtLookup_1000 32566189 34.8 ns/op
BenchmarkHamtLookup_10000 24775086 49.1 ns/op
BenchmarkGoMapLookup_10 69836985 16.3 ns/op
BenchmarkGoMapLookup_100 66960720 16.5 ns/op
BenchmarkGoMapLookup_1000 36865258 30.7 ns/op
BenchmarkGoMapLookup_10000 28110822 43.3 ns/op
BenchmarkHamtInsert_10 8019391 137.0 ns/op
BenchmarkHamtInsert_25 6851881 174.0 ns/op
BenchmarkHamtInsert_50 5419015 221.0 ns/op
BenchmarkHamtInsert_100 3860596 293.0 ns/op
BenchmarkHamtInsert_1000 2596484 469.0 ns/op
BenchmarkHamtInsert_5000 1892996 644.0 ns/op
BenchmarkGoMapInsert_10 17940093 66.5 ns/op
BenchmarkGoMapInsert_25 13996856 74.3 ns/op
BenchmarkGoMapInsert_50 14645752 83.3 ns/op
BenchmarkGoMapInsert_100 14309284 82.8 ns/op
BenchmarkGoMapInsert_1000 10754890 106.0 ns/op
BenchmarkGoMapInsert_5000 11948517 100.0 ns/op
```
Results are from a 2018 MacBook Pro.
`BenchmarkHamt*` and `BenchmarkGo*` are tests with same input using HAMT and native Go maps,
respectively.
Run these benchmarks yourself with `./dev -bench`.
Keep in mind that HAMT is immutable and derivative data structure which requires lots of
memory allocations, compared to the mutable in-place native go maps.
I've chosen to compare the HAMT implementation with Go maps since Go maps are likely what
you are familiar with. :-)