POC for effictively reducing a large data footprint.
A good canidate has been found for implementing our reducer function, however
more tests should be done to push optimization, not that it is needed. Overall,
with harsh benchmarking we expect to see 500~1000 ns/op
(I know quite the
range) depending on configuration and stack size.
More tests need to be performed though so we can determine the memory footprint. I would like to have a good estimate of stackSize to memory consumption.
Pushing the array right to left and popping the first element seems to be rather effective, and probably the fastest way to go about it. Maybe follow up on #darkarts to see what their ideas are. Maybe PonyDev might know too.
toDelete := stack[0]
stack = append(stack[1:], entry)
delete(data, toDelete)
Found a new, potentially better, way of doing thi. See Reducer2. I'll add more information after this flight.
Instead of using the append
function, Reducer manually tracks the current
index and loops around the array, with index+1
being the popped index. From
there it calls the delete
function with whatever being in the slice. We don't
need to check the value of the slice at that index, because delete just doesn't
delete if the value isn't in the map nor does it panic or complain.
If you look at the benchmarks, avoiding the use of append doesn't significantly improve upon speed, however it does look to improve upon memory usage.
The expected usecase is 1000 or so entries per 10 seconds, which the benchmarks blow out of the water. As long as the active memory consumption isn't too great then this will act as a good solution.
goos: linux
goarch: amd64
pkg: reducer
BenchmarkReducer1-4 1542646 753 ns/op 85 B/op 1 allocs/op
BenchmarkReducer2-4 1898156 672 ns/op 23 B/op 1 allocs/op
BenchmarkReducer1Bad-4 2126659 636 ns/op 91 B/op 1 allocs/op
BenchmarkReducer2Bad-4 2353987 575 ns/op 20 B/op 1 allocs/op
BenchmarkRandomString-4 12516368 89.5 ns/op 7 B/op 0 allocs/op
Since I started sharing this out, it's getting cleaned up. Right now this requires go 1.18, since I wanted a good excuse to finally use generics.