mirror of
https://github.com/coredns/coredns.git
synced 2025-11-22 20:02:18 -05:00
plugin/cache: remove superfluous allocations in item.toMsg (#7700)
This commit removes superfluous allocations of the Answer, Ns, and Extra
slices when copying a cached a dns.Msg. The allocations are superfluous
because we immediately overwrite the newly copied slices with
filterRRSlice. It also updates filterRRSlice to pre-calculate the size
of the slice being copied into.
Benchmark results:
goos: darwin
goarch: arm64
pkg: github.com/coredns/coredns/plugin/cache
cpu: Apple M4 Pro
│ base.10.txt │ new.10.txt │
│ sec/op │ sec/op vs base │
CacheResponse-14 471.1n ± 0% 462.9n ± 2% -1.74% (p=0.009 n=10)
│ base.10.txt │ new.10.txt │
│ B/op │ B/op vs base │
CacheResponse-14 672.0 ± 0% 656.0 ± 0% -2.38% (p=0.000 n=10)
│ base.10.txt │ new.10.txt │
│ allocs/op │ allocs/op vs base │
CacheResponse-14 13.00 ± 0% 12.00 ± 0% -7.69% (p=0.000 n=10)
Signed-off-by: Charlie Vieth <charlie.vieth@gmail.com>
This commit is contained in:
11
plugin/cache/cache_test.go
vendored
11
plugin/cache/cache_test.go
vendored
@@ -594,16 +594,25 @@ func BenchmarkCacheResponse(b *testing.B) {
|
|||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
// Add some answers since these need to be duplicated when
|
||||||
|
// serving a cached response.
|
||||||
|
answer := []dns.RR{
|
||||||
|
test.MX("miek.nl. 3601 IN MX 1 aspmx.l.google.com."),
|
||||||
|
test.MX("miek.nl. 3601 IN MX 10 aspmx2.googlemail.com."),
|
||||||
|
}
|
||||||
reqs := make([]*dns.Msg, 5)
|
reqs := make([]*dns.Msg, 5)
|
||||||
for i, q := range []string{"example1", "example2", "a", "b", "ddd"} {
|
for i, q := range []string{"example1", "example2", "a", "b", "ddd"} {
|
||||||
reqs[i] = new(dns.Msg)
|
reqs[i] = new(dns.Msg)
|
||||||
reqs[i].SetQuestion(q+".example.org.", dns.TypeA)
|
reqs[i].SetQuestion(q+".example.org.", dns.TypeA)
|
||||||
|
reqs[i].Answer = answer
|
||||||
}
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
rw := &test.ResponseWriter{}
|
||||||
j := 0
|
j := 0
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
req := reqs[j]
|
req := reqs[j]
|
||||||
c.ServeDNS(ctx, &test.ResponseWriter{}, req)
|
c.ServeDNS(ctx, rw, req)
|
||||||
j = (j + 1) % 5
|
j = (j + 1) % 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
plugin/cache/dnssec.go
vendored
10
plugin/cache/dnssec.go
vendored
@@ -6,8 +6,14 @@ import "github.com/miekg/dns"
|
|||||||
// If dup is true the RRs in rrs are _copied_ before adjusting their
|
// If dup is true the RRs in rrs are _copied_ before adjusting their
|
||||||
// TTL and the slice of copied RRs is returned.
|
// TTL and the slice of copied RRs is returned.
|
||||||
func filterRRSlice(rrs []dns.RR, ttl uint32, dup bool) []dns.RR {
|
func filterRRSlice(rrs []dns.RR, ttl uint32, dup bool) []dns.RR {
|
||||||
|
n := 0
|
||||||
|
for _, r := range rrs {
|
||||||
|
if r.Header().Rrtype != dns.TypeOPT {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rs := make([]dns.RR, n)
|
||||||
j := 0
|
j := 0
|
||||||
rs := make([]dns.RR, len(rrs))
|
|
||||||
for _, r := range rrs {
|
for _, r := range rrs {
|
||||||
if r.Header().Rrtype == dns.TypeOPT {
|
if r.Header().Rrtype == dns.TypeOPT {
|
||||||
continue
|
continue
|
||||||
@@ -20,5 +26,5 @@ func filterRRSlice(rrs []dns.RR, ttl uint32, dup bool) []dns.RR {
|
|||||||
rs[j].Header().Ttl = ttl
|
rs[j].Header().Ttl = ttl
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
return rs[:j]
|
return rs
|
||||||
}
|
}
|
||||||
|
|||||||
4
plugin/cache/item.go
vendored
4
plugin/cache/item.go
vendored
@@ -82,10 +82,6 @@ func (i *item) toMsg(m *dns.Msg, now time.Time, do bool, ad bool) *dns.Msg {
|
|||||||
m1.RecursionAvailable = i.RecursionAvailable
|
m1.RecursionAvailable = i.RecursionAvailable
|
||||||
m1.Rcode = i.Rcode
|
m1.Rcode = i.Rcode
|
||||||
|
|
||||||
m1.Answer = make([]dns.RR, len(i.Answer))
|
|
||||||
m1.Ns = make([]dns.RR, len(i.Ns))
|
|
||||||
m1.Extra = make([]dns.RR, len(i.Extra))
|
|
||||||
|
|
||||||
ttl := uint32(i.ttl(now))
|
ttl := uint32(i.ttl(now))
|
||||||
m1.Answer = filterRRSlice(i.Answer, ttl, true)
|
m1.Answer = filterRRSlice(i.Answer, ttl, true)
|
||||||
m1.Ns = filterRRSlice(i.Ns, ttl, true)
|
m1.Ns = filterRRSlice(i.Ns, ttl, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user