Skip to content

Commit

Permalink
stree: Make Iter faster by using generic sorting function (#5734)
Browse files Browse the repository at this point in the history
This is roughly 4x faster since there are no interface conversions and
reduces allocations.

Signed-off-by: Neil Twigg <neil@nats.io>
  • Loading branch information
derekcollison authored Aug 1, 2024
2 parents 252e432 + 2e7b806 commit 136ef66
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
4 changes: 2 additions & 2 deletions server/stree/stree.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package stree

import (
"bytes"
"sort"
"slices"
)

// SubjectTree is an adaptive radix trie (ART) for storing subject information on literal subjects.
Expand Down Expand Up @@ -382,7 +382,7 @@ func (t *SubjectTree[T]) iter(n node, pre []byte, cb func(subject []byte, val *T
}
}
// Now sort.
sort.SliceStable(nodes, func(i, j int) bool { return bytes.Compare(nodes[i].path(), nodes[j].path()) < 0 })
slices.SortStableFunc(nodes, func(a, b node) int { return bytes.Compare(a.path(), b.path()) })
// Now walk the nodes in order and call into next iter.
for i := range nodes {
if !t.iter(nodes[i], pre, cb) {
Expand Down
20 changes: 20 additions & 0 deletions server/stree/stree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,26 @@ func TestSubjectTreeMatchAllPerf(t *testing.T) {
}
}

func TestSubjectTreeIterPerf(t *testing.T) {
if !*runResults {
t.Skip()
}
st := NewSubjectTree[int]()

for i := 0; i < 1_000_000; i++ {
subj := fmt.Sprintf("subj.%d.%d", rand.Intn(100)+1, i)
st.Insert(b(subj), 22)
}

start := time.Now()
count := 0
st.Iter(func(_ []byte, _ *int) bool {
count++
return true
})
t.Logf("Iter took %s and matched %d entries", time.Since(start), count)
}

func TestSubjectTreeNode48(t *testing.T) {
var a, b, c leaf[int]
var n node48
Expand Down

0 comments on commit 136ef66

Please sign in to comment.