mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 00:04:15 -04:00
perf(kubernetes): optimize AutoPath slice allocation (#7323)
Pre-allocate slice capacity in AutoPath to eliminate unnecessary memory reallocations. This avoids slice growth when appending search domains and sentinel value. Benchmark shows significant performance improvement: - Before: 538.6 ns/op, 560 B/op, 13 allocs/op - After: 436.8 ns/op, 336 B/op, 11 allocs/op - Result: 19% faster, 40% less memory, 15% fewer allocations The optimization benefits Kubernetes clusters using autopath for server-side search path completion. Adds benchmark test to measure AutoPath performance. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
@@ -33,15 +33,12 @@ func (k *Kubernetes) AutoPath(state request.Request) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
search := make([]string, 3)
|
||||
totalSize := 3 + len(k.autoPathSearch) + 1 // +1 for sentinel
|
||||
search := make([]string, 0, totalSize)
|
||||
if zone == "." {
|
||||
search[0] = pod.Namespace + ".svc."
|
||||
search[1] = "svc."
|
||||
search[2] = "."
|
||||
search = append(search, pod.Namespace+".svc.", "svc.", ".")
|
||||
} else {
|
||||
search[0] = pod.Namespace + ".svc." + zone
|
||||
search[1] = "svc." + zone
|
||||
search[2] = zone
|
||||
search = append(search, pod.Namespace+".svc."+zone, "svc."+zone, zone)
|
||||
}
|
||||
|
||||
search = append(search, k.autoPathSearch...)
|
||||
|
||||
77
plugin/kubernetes/autopath_test.go
Normal file
77
plugin/kubernetes/autopath_test.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/coredns/coredns/plugin/kubernetes/object"
|
||||
"github.com/coredns/coredns/plugin/test"
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
api "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// Mock data for benchmarks
|
||||
var (
|
||||
mockPod = &object.Pod{
|
||||
Namespace: "test-namespace",
|
||||
}
|
||||
mockAutoPathSearch = []string{"example.com", "internal.example.com", "cluster.local"}
|
||||
)
|
||||
|
||||
// Mock API connector for testing
|
||||
type mockAPIConnector struct{}
|
||||
|
||||
func (m *mockAPIConnector) PodIndex(ip string) []*object.Pod {
|
||||
return []*object.Pod{mockPod}
|
||||
}
|
||||
|
||||
// Minimal implementation of other required methods
|
||||
func (m *mockAPIConnector) ServiceList() []*object.Service { return nil }
|
||||
func (m *mockAPIConnector) EndpointsList() []*object.Endpoints { return nil }
|
||||
func (m *mockAPIConnector) ServiceImportList() []*object.ServiceImport { return nil }
|
||||
func (m *mockAPIConnector) SvcIndex(s string) []*object.Service { return nil }
|
||||
func (m *mockAPIConnector) SvcIndexReverse(s string) []*object.Service { return nil }
|
||||
func (m *mockAPIConnector) SvcExtIndexReverse(s string) []*object.Service { return nil }
|
||||
func (m *mockAPIConnector) SvcImportIndex(s string) []*object.ServiceImport { return nil }
|
||||
func (m *mockAPIConnector) EpIndex(s string) []*object.Endpoints { return nil }
|
||||
func (m *mockAPIConnector) EpIndexReverse(s string) []*object.Endpoints { return nil }
|
||||
func (m *mockAPIConnector) McEpIndex(s string) []*object.MultiClusterEndpoints { return nil }
|
||||
func (m *mockAPIConnector) GetNodeByName(ctx context.Context, name string) (*api.Node, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockAPIConnector) GetNamespaceByName(name string) (*object.Namespace, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (m *mockAPIConnector) Run() {}
|
||||
func (m *mockAPIConnector) HasSynced() bool { return true }
|
||||
func (m *mockAPIConnector) Stop() error { return nil }
|
||||
func (m *mockAPIConnector) Modified(ModifiedMode) int64 { return 0 }
|
||||
|
||||
func BenchmarkAutoPath(b *testing.B) {
|
||||
k := &Kubernetes{
|
||||
Zones: []string{"cluster.local."},
|
||||
autoPathSearch: mockAutoPathSearch,
|
||||
podMode: podModeVerified,
|
||||
opts: dnsControlOpts{
|
||||
initPodCache: true,
|
||||
},
|
||||
APIConn: &mockAPIConnector{},
|
||||
}
|
||||
|
||||
// Create a mock DNS request
|
||||
req := &dns.Msg{}
|
||||
req.SetQuestion("test.cluster.local.", dns.TypeA)
|
||||
|
||||
// Create a request state with a mock ResponseWriter
|
||||
state := request.Request{W: &test.ResponseWriter{}, Req: req}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
result := k.AutoPath(state)
|
||||
_ = result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user