Conversation
joamaki
force-pushed
the
pr/joamaki/part-optimizations
branch
from
September 25, 2026 10:59
db90fda to
b73468d
Compare
|
joamaki
force-pushed
the
pr/joamaki/part-optimizations
branch
from
September 25, 2026 14:28
dc81304 to
32ff31e
Compare
…ration
Prefix and lower bound searches on a non-unique index keep a set of the
visited primary keys to not yield the same object twice. Inserting into
the set with string(primary) copied the key, allocating once per yielded
object.
The keys are slices of the keys stored in the tree, which are never
mutated, so refer to them directly with unsafe.String.
Add a benchmark for lower bound search on a non-unique index.
│ old │ new │
│ sec/op │ sec/op vs base │
DB_Prefix_SecondaryIndex 87.38µ ± 2% 75.62µ ± 2% -13.47% (p=0.000 n=8)
DB_LowerBound_SecondaryIndex 88.67µ ± 1% 79.71µ ± 6% -10.11% (p=0.000 n=8)
geomean 88.02µ 77.63µ -11.80%
│ old │ new │
│ objects/sec │ objects/sec vs base │
DB_Prefix_SecondaryIndex 11.44M ± 11% 13.22M ± 2% +15.56% (p=0.000 n=8)
DB_LowerBound_SecondaryIndex 11.28M ± 2% 12.55M ± 7% +11.25% (p=0.000 n=8)
geomean 11.36M 12.88M +13.39%
│ old │ new │
│ B/op │ B/op vs base │
DB_Prefix_SecondaryIndex 122.0Ki ± 0% 106.4Ki ± 0% -12.80% (p=0.000 n=8)
DB_LowerBound_SecondaryIndex 122.4Ki ± 0% 106.8Ki ± 0% -12.77% (p=0.000 n=8)
geomean 122.2Ki 106.6Ki -12.79%
│ old │ new │
│ allocs/op │ allocs/op vs base │
DB_Prefix_SecondaryIndex 1026.00 ± 0% 26.00 ± 0% -97.47% (p=0.000 n=8)
DB_LowerBound_SecondaryIndex 1031.00 ± 0% 31.00 ± 0% -96.99% (p=0.000 n=8)
geomean 1.028k 28.39 -97.24%
AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
List() in a write transaction cloned the index transaction to get a
snapshot for the returned iterator. For a unique index the lookup is a
Get() and the returned singleton iterator does not refer to the tree,
so the snapshot is unnecessary. The clone was costly as it froze the
nodes in the transaction, forcing the next write to clone them again.
Query the transaction directly for unique indexes and add a benchmark
for List() followed by Insert() in a write transaction.
│ old │ new │
│ sec/op │ sec/op vs base │
DB_ListInsert 1409.9µ ± 2% 473.3µ ± 3% -66.43% (p=0.000 n=8)
│ old │ new │
│ objects/sec │ objects/sec vs base │
DB_ListInsert 709.3k ± 2% 2112.6k ± 6% +197.85% (p=0.000 n=8)
│ old │ new │
│ B/op │ B/op vs base │
DB_ListInsert 2913.2Ki ± 0% 475.2Ki ± 0% -83.69% (p=0.000 n=8)
│ old │ new │
│ allocs/op │ allocs/op vs base │
DB_ListInsert 14.08k ± 0% 11.07k ± 0% -21.37% (p=0.000 n=8)
AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
The lower bound search allocated a single element slice for the node at
which the search ended and grew the slice of edges to explore one edge
at a time.
Slice the node from its parent's children instead (only the starting
node needs the allocation) and preallocate a small capacity for the
edges. This brings the lower bound search down to a single allocation
in the common case.
Add a benchmark for LowerBound().
│ old │ new │
│ sec/op │ sec/op vs base │
LowerBound 132.47µ ± 4% 73.53µ ± 4% -44.49% (p=0.000 n=8)
│ old │ new │
│ objects/sec │ objects/sec vs base │
LowerBound 7.549M ± 4% 13.600M ± 5% +80.16% (p=0.000 n=8)
│ old │ new │
│ B/op │ B/op vs base │
LowerBound 157.8Ki ± 0% 101.6Ki ± 0% -35.66% (p=0.000 n=8)
│ old │ new │
│ allocs/op │ allocs/op vs base │
LowerBound 4.767k ± 0% 2.000k ± 0% -58.04% (p=0.000 n=8)
AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
The lower bound search found the smallest child equal to or larger than
the key with a binary search over the children, reading the key from
each probed child's header. findIndex() finds the same position from
the node's own key array or bitmap without touching the children.
Add a lower bound benchmark with random keys in a larger tree, which
exercises all the node kinds (sequential keys mostly produce node256s).
│ old │ new │
│ sec/op │ sec/op vs base │
LowerBound 73.96µ ± 1% 73.33µ ± 1% -0.84% (p=0.005 n=10)
LowerBound_Random 117.29µ ± 17% 92.50µ ± 21% -21.13% (p=0.003 n=10)
geomean 93.13µ 82.36µ -11.57%
│ old │ new │
│ objects/sec │ objects/sec vs base │
LowerBound 13.52M ± 1% 13.64M ± 1% +0.85% (p=0.005 n=10)
LowerBound_Random 8.526M ± 21% 10.811M ± 18% +26.80% (p=0.003 n=10)
geomean 10.74M 12.14M +13.08%
│ old │ new │
│ B/op │ B/op vs base │
LowerBound 101.6Ki ± 0% 101.6Ki ± 0% ~ (p=1.000 n=10) ¹
LowerBound_Random 94.12Ki ± 0% 94.12Ki ± 0% ~ (p=1.000 n=10)
geomean 97.77Ki 97.77Ki +0.00%
¹ all samples are equal
│ old │ new │
│ allocs/op │ allocs/op vs base │
LowerBound 2.000k ± 0% 2.000k ± 0% ~ (p=1.000 n=10) ¹
LowerBound_Random 1.002k ± 0% 1.002k ± 0% ~ (p=1.000 n=10) ¹
geomean 1.416k 1.416k +0.00%
¹ all samples are equal
AIL:3
Signed-off-by: Jussi Maki <jussi@isovalent.com>
joamaki
force-pushed
the
pr/joamaki/part-optimizations
branch
from
September 30, 2026 07:16
32ff31e to
1126955
Compare
joamaki
marked this pull request as ready for review
September 30, 2026 07:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[]*header[T]{this}by instead slicing it from the part node's children array. (DB_LowerBound_SecondaryIndex 31 allocs => 28 allocs)AIL:3