Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark batch lookups vs. MapIterator, remove MapIterator.prevKey #1077

Merged
merged 2 commits into from
Jun 28, 2023

Conversation

ti-mo
Copy link
Collaborator

@ti-mo ti-mo commented Jun 26, 2023

Since MapIterator is an interesting target for optimization through the upcoming zero-copy map ops work, add a benchmark and simplify its internal representation a bit.

Benchmark results at time of writing:

BenchmarkIterate/MapIterator-16         	             866	   1457681 ns/op	   64126 B/op	    4004 allocs/op
BenchmarkIterate/MapIteratorDelete-16   	             408	   2526392 ns/op	   80210 B/op	    6004 allocs/op
BenchmarkIterate/BatchLookup-16         	           59647	     19974 ns/op	   32851 B/op	       8 allocs/op
BenchmarkIterate/BatchLookupAndDelete-16         	   10000	    154757 ns/op	   32872 B/op	       8 allocs/op
BenchmarkIterate/BatchDelete-16                  	    8306	    136770 ns/op	   16416 B/op	       3 allocs/op
Change the terminology used in the iterator to revolve around the 'current'
and the 'next' key instead of considering the 'previous' key.

I found the behaviour after passing a nil `mi.prevKey` to NextKeyBytes a little
subtle. If the interface value passed to NextKeyBytes contains a nil 'any', it
will successfully detect nilness and not try to marshal the key. If the caller
passes a []byte(nil), the nil check will fail and nextKey() will try to marshal
the key.

Perform a nil check on mi.curKey instead and explicitly pass an untyped nil to
NextKeyBytes if the Map's first key needs to be looked up. This means prevKey
can be eliminated.

@ti-mo ti-mo requested review from lmb and rgo3 June 26, 2023 12:52
map_test.go Outdated Show resolved Hide resolved
// non-nil interface and try to marshal it.
nextKey, mi.err = mi.target.NextKeyBytes(nil)

mi.curKey = make([]byte, mi.target.keySize)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a bit weird: for an empty map we get mi.curKey != nil due to this. Not sure if it's worth fixing though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out, I think that's okay for now. No other methods depend on this state.

Benchmark results at time of writing:

BenchmarkIterate/MapIterator-16         	             866	   1457681 ns/op	   64126 B/op	    4004 allocs/op
BenchmarkIterate/MapIteratorDelete-16   	             408	   2526392 ns/op	   80210 B/op	    6004 allocs/op
BenchmarkIterate/BatchLookup-16         	           59647	     19974 ns/op	   32851 B/op	       8 allocs/op
BenchmarkIterate/BatchLookupAndDelete-16         	   10000	    154757 ns/op	   32872 B/op	       8 allocs/op
BenchmarkIterate/BatchDelete-16                  	    8306	    136770 ns/op	   16416 B/op	       3 allocs/op

Signed-off-by: Timo Beckers <timo@isovalent.com>
Change the terminology used in the iterator to revolve around the 'current'
and the 'next' key instead of considering the 'previous' key.

I found the behaviour after passing a nil `mi.prevKey` to NextKeyBytes a little
subtle. If the interface value passed to NextKeyBytes contains a nil 'any', it
will successfully detect nilness and not try to marshal the key. If the caller
passes a []byte(nil), the nil check will fail and nextKey() will try to marshal
the key.

Perform a nil check on mi.curKey instead and explicitly pass an untyped nil to
NextKeyBytes if the Map's first key needs to be looked up. This means prevKey
can be eliminated.

Signed-off-by: Timo Beckers <timo@isovalent.com>
@lmb lmb merged commit be9a38d into cilium:master Jun 28, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants