Skip to content

Commit 4c8d1ad

Browse files
GODRIVER-2526 Optimize description.selectByKind. (#1059)
* GODRIVER-2526 Optimize description.selectByKind by eliminating struct appending. Co-authored-by: Benjamin Rewis <[email protected]>
1 parent 988abba commit 4c8d1ad

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

mongo/description/selector_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,35 @@ func TestSelector_Sharded(t *testing.T) {
230230
require.Equal([]Server{s}, result)
231231
}
232232

233+
func BenchmarkSelector_Sharded(b *testing.B) {
234+
subject := readpref.Primary()
235+
236+
s := Server{
237+
Addr: address.Address("localhost:27017"),
238+
HeartbeatInterval: time.Duration(10) * time.Second,
239+
LastWriteTime: time.Date(2017, 2, 11, 14, 0, 0, 0, time.UTC),
240+
LastUpdateTime: time.Date(2017, 2, 11, 14, 0, 2, 0, time.UTC),
241+
Kind: Mongos,
242+
WireVersion: &VersionRange{Min: 0, Max: 5},
243+
}
244+
servers := make([]Server, 100)
245+
for i := 0; i < len(servers); i++ {
246+
servers[i] = s
247+
}
248+
servers[0].Kind = LoadBalancer
249+
c := Topology{
250+
Kind: Sharded,
251+
Servers: servers,
252+
}
253+
254+
b.ResetTimer()
255+
b.RunParallel(func(p *testing.PB) {
256+
for p.Next() {
257+
_, _ = ReadPrefSelector(subject).SelectServer(c, c.Servers)
258+
}
259+
})
260+
}
261+
233262
func TestSelector_Single(t *testing.T) {
234263
t.Parallel()
235264

mongo/description/server_selector.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,18 @@ func selectByTagSet(candidates []Server, tagSets []tag.Set) []Server {
296296
}
297297

298298
func selectByKind(candidates []Server, kind ServerKind) []Server {
299-
var result []Server
300-
for _, s := range candidates {
299+
// Record the indices of viable candidates first and then append those to the returned slice
300+
// to avoid appending costly Server structs directly as an optimization.
301+
viableIndexes := make([]int, 0, len(candidates))
302+
for i, s := range candidates {
301303
if s.Kind == kind {
302-
result = append(result, s)
304+
viableIndexes = append(viableIndexes, i)
303305
}
304306
}
305-
307+
result := make([]Server, len(viableIndexes))
308+
for i, idx := range viableIndexes {
309+
result[i] = candidates[idx]
310+
}
306311
return result
307312
}
308313

0 commit comments

Comments
 (0)