Files
coredns/plugin/file/tree/less_test.go

236 lines
6.3 KiB
Go
Raw Normal View History

package tree
import (
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
"bytes"
"cmp"
"slices"
"strings"
"sync"
"testing"
"github.com/miekg/dns"
)
func TestLess(t *testing.T) {
tests := []struct {
in []string
out []string
}{
{
[]string{"aaa.powerdns.de.", "bbb.powerdns.net.", "xxx.powerdns.com."},
[]string{"xxx.powerdns.com.", "aaa.powerdns.de.", "bbb.powerdns.net."},
},
{
[]string{"aaa.POWERDNS.de.", "bbb.PoweRdnS.net.", "xxx.powerdns.com."},
[]string{"xxx.powerdns.com.", "aaa.POWERDNS.de.", "bbb.PoweRdnS.net."},
},
{
[]string{"aaa.aaaa.aa.", "aa.aaa.a.", "bbb.bbbb.bb."},
[]string{"aa.aaa.a.", "aaa.aaaa.aa.", "bbb.bbbb.bb."},
},
{
[]string{"aaaaa.", "aaa.", "bbb."},
[]string{"aaa.", "aaaaa.", "bbb."},
},
{
[]string{"a.a.a.a.", "a.a.", "a.a.a."},
[]string{"a.a.", "a.a.a.", "a.a.a.a."},
},
{
[]string{"example.", "z.example.", "a.example."},
[]string{"example.", "a.example.", "z.example."},
},
{
[]string{"a.example.", "Z.a.example.", "z.example.", "yljkjljk.a.example.", "\\001.z.example.", "example.", "*.z.example.", "\\200.z.example.", "zABC.a.EXAMPLE."},
[]string{"example.", "a.example.", "yljkjljk.a.example.", "Z.a.example.", "zABC.a.EXAMPLE.", "z.example.", "\\001.z.example.", "*.z.example.", "\\200.z.example."},
},
{
// RFC3034 example.
[]string{"a.example.", "Z.a.example.", "z.example.", "yljkjljk.a.example.", "example.", "*.z.example.", "zABC.a.EXAMPLE."},
[]string{"example.", "a.example.", "yljkjljk.a.example.", "Z.a.example.", "zABC.a.EXAMPLE.", "z.example.", "*.z.example."},
},
}
Tests:
for j, test := range tests {
slices.SortFunc(test.in, less)
for i := range len(test.in) {
if test.in[i] != test.out[i] {
t.Errorf("Test %d: expected %s, got %s", j, test.out[i], test.in[i])
n := ""
for k, in := range test.in {
if k+1 == len(test.in) {
n = "\n"
}
t.Logf("%s <-> %s\n%s", in, test.out[k], n)
}
continue Tests
}
}
}
}
// Test that concurrent calls to Less (which calls Elem.Name) do not race or panic.
// See issue #7561 for reference.
func TestLess_ConcurrentNameAccess(t *testing.T) {
rr, err := dns.NewRR("a.example. 3600 IN A 1.2.3.4")
if err != nil {
t.Fatalf("failed to create RR: %v", err)
}
e := newElem(rr)
const n = 200
var wg sync.WaitGroup
wg.Add(n)
for range n {
go func() {
defer wg.Done()
// Compare the same name repeatedly; previously this could race due to lazy Name() writes.
_ = Less(e, "a.example.")
_ = e.Name()
}()
}
wg.Wait()
}
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
func TestLess_EdgeCases(t *testing.T) {
// For every case four variants are synthesized:
// - a b
// - a. b
// - a b.
// - a. b.
//
// For each variant commutativity is tested.
tests := []struct {
a, b string
variants bool
want int
}{
{``, ``, true, 0},
{``, `\000`, true, -1},
{``, `\.`, true, -1},
{`\.`, `\.`, true, 0},
{``, `example`, true, -1},
{`example`, `example`, true, 0},
{`a\.example`, `a.example`, true, -1},
{`a.example`, `a-b.example`, true, -1},
{`a.example`, `a*.example`, true, -1},
{`a.example`, `a\000.example`, true, -1},
{`a.eXaMpLe`, `a.example`, true, 0},
{`\000\0320 \"\046@*`, `\000\032\048\032\034\046\064\042`, true, 0},
{`<=>?@ABCDE`, `\060\061\062\063\064\065\066\067\068\069`, true, 0},
{`<=>?@ABCDE`, `\060\061\062\063\064\097\098\099\100\101`, true, 0},
{`café.example`, `CAFÉ.example`, true, 1}, // é (\195\169) > É (\195\137)
{`\\065.example`, `\\097.example`, true, -1},
{``, `\`, false, 0},
{`a\.b.example`, `a\046b.example`, true, 0},
{`0.example`, `\0.example`, true, 0},
{`01.example`, `\01.example`, true, 0},
{`a\.b.example`, `a\046b.example`, true, 0},
{`\\.example`, `\092.example`, true, 0},
}
for i, test := range tests {
variants := []struct{ a, b string }{
{test.a, test.b},
{test.a + `.`, test.b},
{test.a, test.b + `.`},
{test.a + `.`, test.b + `.`},
}
if !test.variants {
variants = variants[:1]
}
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
for _, variant := range variants {
if got := less(variant.a, variant.b); cmp.Compare(got, 0) != test.want {
t.Errorf("Test %d: expected less(%s, %s)=%d, got %d", i, variant.a, variant.b, test.want, cmp.Compare(got, 0))
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
}
if got := less(variant.b, variant.a); cmp.Compare(got, 0) != -test.want {
t.Errorf("Test %d: expected less(%s, %s)=%d, got %d", i, variant.b, variant.a, -test.want, cmp.Compare(got, 0))
}
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
}
}
}
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
func BenchmarkLess(b *testing.B) {
tests := [][]string{
Performance tuning for plugin/file (#7658) * plugin/file: improve performance of function tree.less(..) PrevLabel always begins its iteration from the tail of domain name. less(..) loop can improve its performance by calling PrevLabel starting from the last processed label. As the benchmark results showed, the performance is improved by about 15%. $ go test -bench=Less -run=^$ goos: linux goarch: amd64 pkg: github.com/coredns/coredns/plugin/file/tree cpu: Intel(R) Xeon(R) Platinum 8336C CPU @ 2.30GHz BenchmarkLess/base-16 99003 12105 ns/op BenchmarkLess/optimized-16 114522 10590 ns/op PASS ok github.com/coredns/coredns/plugin/file/tree 2.416s Signed-off-by: yuwenchao <ywc689@163.com> * plugin/file: performance enhancement for nameFromRight(..) Similar to tree.less(..), performance of function nameFromRight can boost by utilizing dns.PrevLabel more efficiently. As benchmark tests shown, performance of this function with the optimization is gained by double or triple. * Benchmark test result for the original implementation: BenchmarkNameFromRight/i0_origin-16 430719652 2.794 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 30933135 37.52 ns/op BenchmarkNameFromRight/two_labels_i1-16 29375857 40.71 ns/op BenchmarkNameFromRight/two_labels_i2-16 18556830 63.97 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 14678812 84.73 ns/op BenchmarkNameFromRight/ten_labels_i5-16 8522132 133.0 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 3154410 378.2 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 35297224 33.59 ns/op BenchmarkNameFromRightRandomized-16 10638702 113.4 ns/op 0 B/op 0 allocs/op * Benchmark test result with this optimization: BenchmarkNameFromRight/i0_origin-16 425864671 2.808 ns/op BenchmarkNameFromRight/eq_origin_i1_shot-16 60903428 19.53 ns/op BenchmarkNameFromRight/two_labels_i1-16 50209297 24.21 ns/op BenchmarkNameFromRight/two_labels_i2-16 42483711 27.88 ns/op BenchmarkNameFromRight/two_labels_i3_shot-16 40898925 29.24 ns/op BenchmarkNameFromRight/ten_labels_i5-16 27916532 44.54 ns/op BenchmarkNameFromRight/ten_labels_i11_shot-16 17540040 67.59 ns/op BenchmarkNameFromRight/not_subdomain_shot-16 67180514 17.46 ns/op BenchmarkNameFromRightRandomized-16 32692081 38.21 ns/op 0 B/op 0 allocs/op Signed-off-by: yuwenchao <yuwenchao@bytedance.com> --------- Signed-off-by: yuwenchao <ywc689@163.com> Signed-off-by: yuwenchao <yuwenchao@bytedance.com> Co-authored-by: yuwenchao <yuwenchao@bytedance.com>
2025-11-07 05:12:49 +08:00
{"aaa.powerdns.de", "bbb.powerdns.net.", "xxx.powerdns.com."},
{"aaa.POWERDNS.de", "bbb.PoweRdnS.net.", "xxx.powerdns.com."},
{"aaa.aaaa.aa.", "aa.aaa.a.", "bbb.bbbb.bb."},
{"aaaaa.", "aaa.", "bbb."},
{"a.a.a.a.", "a.a.", "a.a.a."},
{"example.", "z.example.", "a.example."},
{"a.example.", "Z.a.example.", "z.example.", "yljkjljk.a.example.", "\\001.z.example.", "example.", "*.z.example.", "\\200.z.example.", "zABC.a.EXAMPLE."},
{"a.example.", "Z.a.example.", "z.example.", "yljkjljk.a.example.", "example.", "*.z.example.", "zABC.a.EXAMPLE."},
}
b.ResetTimer()
b.Run("base", func(b *testing.B) {
for b.Loop() {
for _, t := range tests {
for m := range len(t) - 1 {
for n := m + 1; n < len(t); n++ {
less0(t[m], t[n])
}
}
}
}
})
b.Run("optimized", func(b *testing.B) {
for b.Loop() {
for _, t := range tests {
for m := range len(t) - 1 {
for n := m + 1; n < len(t); n++ {
less(t[m], t[n])
}
}
}
}
})
}
// The original less function, serving as the benchmark test baseline.
func less0(a, b string) int {
i := 1
aj := len(a)
bj := len(b)
for {
ai, oka := dns.PrevLabel(a, i)
bi, okb := dns.PrevLabel(b, i)
if oka && okb {
return 0
}
// sadly this []byte will allocate... TODO(miek): check if this is needed
// for a name, otherwise compare the strings.
ab := []byte(strings.ToLower(a[ai:aj]))
bb := []byte(strings.ToLower(b[bi:bj]))
doDDD(ab)
doDDD(bb)
res := bytes.Compare(ab, bb)
if res != 0 {
return res
}
i++
aj, bj = ai, bi
}
}
func doDDD(b []byte) {
lb := len(b)
for i := 0; i < lb; i++ {
if i+3 < lb && b[i] == '\\' && isDigit(b[i+1]) && isDigit(b[i+2]) && isDigit(b[i+3]) {
b[i] = dddToByte(b[i:])
for j := i + 1; j < lb-3; j++ {
b[j] = b[j+3]
}
lb -= 3
}
}
}
func isDigit(b byte) bool { return b >= '0' && b <= '9' }
func dddToByte(s []byte) byte { return (s[1]-'0')*100 + (s[2]-'0')*10 + (s[3] - '0') }