Skip to content

Instantly share code, notes, and snippets.

@benburkert
Created June 12, 2017 03:49
Show Gist options
  • Save benburkert/b8c0c407604a3f673a58d53987012d19 to your computer and use it in GitHub Desktop.
Save benburkert/b8c0c407604a3f673a58d53987012d19 to your computer and use it in GitHub Desktop.
BenchmarkName
name old time/op new time/op delta
Name/abc.xzy.-8 274ns ± 1% 472ns ± 0% +72.30% (p=0.000 n=10+9)
Name/ab.cde.fgh.ijk.lmn.opq.rst.uvw.xyz.-8 1.32µs ± 2% 2.19µs ± 0% +66.61% (p=0.000 n=10+9)
Name/example.com.-8 446ns ± 1% 1140ns ± 1% +155.89% (p=0.000 n=10+10)
Name/bar.example.com.-8 451ns ± 2% 1014ns ± 1% +124.86% (p=0.000 n=10+9)
Name/foo.bar.example.com.-8 455ns ± 0% 843ns ± 1% +85.34% (p=0.000 n=8+10)
Name/xyz.foo.bar.example.com.-8 536ns ± 1% 1703ns ± 1% +217.67% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
Name/abc.xzy.-8 32.0B ± 0% 536.0B ± 0% +1575.00% (p=0.000 n=10+10)
Name/ab.cde.fgh.ijk.lmn.opq.rst.uvw.xyz.-8 584B ± 0% 2888B ± 0% +394.52% (p=0.000 n=10+10)
Name/example.com.-8 16.0B ± 0% 932.0B ± 0% +5725.00% (p=0.000 n=10+10)
Name/bar.example.com.-8 16.0B ± 0% 672.0B ± 0% +4100.00% (p=0.000 n=10+10)
Name/foo.bar.example.com.-8 32.0B ± 0% 416.0B ± 0% +1200.00% (p=0.000 n=10+10)
Name/xyz.foo.bar.example.com.-8 32.0B ± 0% 1735.0B ± 0% +5321.88% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
Name/abc.xzy.-8 3.00 ± 0% 4.00 ± 0% +33.33% (p=0.000 n=10+10)
Name/ab.cde.fgh.ijk.lmn.opq.rst.uvw.xyz.-8 6.00 ± 0% 17.00 ± 0% +183.33% (p=0.000 n=10+10)
Name/example.com.-8 1.00 ± 0% 3.00 ± 0% +200.00% (p=0.000 n=10+10)
Name/bar.example.com.-8 1.00 ± 0% 2.00 ± 0% +100.00% (p=0.000 n=10+10)
Name/foo.bar.example.com.-8 1.00 ± 0% 1.00 ± 0% ~ (all samples are equal)
Name/xyz.foo.bar.example.com.-8 1.00 ± 0% 6.00 ± 0% +500.00% (p=0.000 n=10+10)
commit 39969914895ebe006f2eecbf0ba3fc65709aa0ed
Author: Ben Burkert <ben@benburkert.com>
Date: Sun Jun 11 19:57:59 2017 -0700
dns/dnsmessage: benchmark packName/unpackName
Change-Id: Iccf17f2b5b5413bbbfce4a681db2cf0aad439c80
diff --git a/dns/dnsmessage/message.go b/dns/dnsmessage/message.go
index da43b0b..9adfc79 100644
--- a/dns/dnsmessage/message.go
+++ b/dns/dnsmessage/message.go
@@ -599,20 +599,25 @@ func (m *Message) Unpack(msg []byte) error {
// Pack packs a full Message.
func (m *Message) Pack() ([]byte, error) {
+ msg, _, err := m.pack()
+ return msg, err
+}
+
+func (m *Message) pack() ([]byte, map[string]int, error) {
// Validate the lengths. It is very unlikely that anyone will try to
// pack more than 65535 of any particular type, but it is possible and
// we should fail gracefully.
if len(m.Questions) > int(^uint16(0)) {
- return nil, errTooManyQuestions
+ return nil, nil, errTooManyQuestions
}
if len(m.Answers) > int(^uint16(0)) {
- return nil, errTooManyAnswers
+ return nil, nil, errTooManyAnswers
}
if len(m.Authorities) > int(^uint16(0)) {
- return nil, errTooManyAuthorities
+ return nil, nil, errTooManyAuthorities
}
if len(m.Additionals) > int(^uint16(0)) {
- return nil, errTooManyAdditionals
+ return nil, nil, errTooManyAdditionals
}
var h header
@@ -643,32 +648,32 @@ func (m *Message) Pack() ([]byte, error) {
var err error
msg, err = q.pack(msg, compression)
if err != nil {
- return nil, &nestedError{"packing Question", err}
+ return nil, nil, &nestedError{"packing Question", err}
}
}
for _, a := range m.Answers {
var err error
msg, err = packResource(msg, a, compression)
if err != nil {
- return nil, &nestedError{"packing Answer", err}
+ return nil, nil, &nestedError{"packing Answer", err}
}
}
for _, a := range m.Authorities {
var err error
msg, err = packResource(msg, a, compression)
if err != nil {
- return nil, &nestedError{"packing Authority", err}
+ return nil, nil, &nestedError{"packing Authority", err}
}
}
for _, a := range m.Additionals {
var err error
msg, err = packResource(msg, a, compression)
if err != nil {
- return nil, &nestedError{"packing Additional", err}
+ return nil, nil, &nestedError{"packing Additional", err}
}
}
- return msg, nil
+ return msg, compression, nil
}
// An ResourceHeader is the header of a DNS resource record. There are
diff --git a/dns/dnsmessage/message_test.go b/dns/dnsmessage/message_test.go
index 46edd72..2f4de29 100644
--- a/dns/dnsmessage/message_test.go
+++ b/dns/dnsmessage/message_test.go
@@ -376,6 +376,55 @@ func ExampleHeaderSearch() {
// Found A/AAAA records for name bar.example.com.: [127.0.0.2]
}
+func BenchmarkName(b *testing.B) {
+ m := largeTestMsg()
+ msg, compression, err := m.pack()
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ benchmarks := []struct {
+ name string
+
+ comp map[string]int
+ msg []byte
+ }{
+ {"abc.xzy.", nil, nil},
+ {"ab.cde.fgh.ijk.lmn.opq.rst.uvw.xyz.", nil, nil},
+ {"example.com.", compression, msg},
+ {"bar.example.com.", compression, msg},
+ {"foo.bar.example.com.", compression, msg},
+ {"xyz.foo.bar.example.com.", compression, msg},
+ }
+
+ for _, bench := range benchmarks {
+ b.Run(bench.name, func(b *testing.B) {
+ b.ReportAllocs()
+
+ for i := 0; i < b.N; i++ {
+ comp := make(map[string]int, len(bench.comp))
+ for k, v := range bench.comp {
+ comp[k] = v
+ }
+
+ buf, err := packName(bench.msg, bench.name, comp)
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ name, _, err := unpackName(buf, len(bench.msg))
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ if name != bench.name {
+ b.Fatal("roundtrip error")
+ }
+ }
+ })
+ }
+}
+
func largeTestMsg() Message {
return Message{
Header: Header{Response: true, Authoritative: true},
commit f953d115e5a56ad000f3076a213eaa47281bc7f7
Author: Ben Burkert <ben@benburkert.com>
Date: Sun Jun 11 18:53:44 2017 -0700
dns/dnsmessage: benchmark Name
Change-Id: I298e82dc52580ef63e794ca41416f37530386919
diff --git a/dns/dnsmessage/message.go b/dns/dnsmessage/message.go
index 71917a7..c47999c 100644
--- a/dns/dnsmessage/message.go
+++ b/dns/dnsmessage/message.go
@@ -777,20 +777,25 @@ func (m *Message) Unpack(msg []byte) error {
// Pack packs a full Message.
func (m *Message) Pack() ([]byte, error) {
+ msg, _, err := m.pack()
+ return msg, err
+}
+
+func (m *Message) pack() ([]byte, map[string]int, error) {
// Validate the lengths. It is very unlikely that anyone will try to
// pack more than 65535 of any particular type, but it is possible and
// we should fail gracefully.
if len(m.Questions) > int(^uint16(0)) {
- return nil, errTooManyQuestions
+ return nil, nil, errTooManyQuestions
}
if len(m.Answers) > int(^uint16(0)) {
- return nil, errTooManyAnswers
+ return nil, nil, errTooManyAnswers
}
if len(m.Authorities) > int(^uint16(0)) {
- return nil, errTooManyAuthorities
+ return nil, nil, errTooManyAuthorities
}
if len(m.Additionals) > int(^uint16(0)) {
- return nil, errTooManyAdditionals
+ return nil, nil, errTooManyAdditionals
}
var h header
@@ -818,29 +823,29 @@ func (m *Message) Pack() ([]byte, error) {
for i := range m.Questions {
var err error
if msg, err = m.Questions[i].pack(msg, compression); err != nil {
- return nil, &nestedError{"packing Question", err}
+ return nil, nil, &nestedError{"packing Question", err}
}
}
for i := range m.Answers {
var err error
if msg, err = m.Answers[i].pack(msg, compression); err != nil {
- return nil, &nestedError{"packing Answer", err}
+ return nil, nil, &nestedError{"packing Answer", err}
}
}
for i := range m.Authorities {
var err error
if msg, err = m.Authorities[i].pack(msg, compression); err != nil {
- return nil, &nestedError{"packing Authority", err}
+ return nil, nil, &nestedError{"packing Authority", err}
}
}
for i := range m.Additionals {
var err error
if msg, err = m.Additionals[i].pack(msg, compression); err != nil {
- return nil, &nestedError{"packing Additional", err}
+ return nil, nil, &nestedError{"packing Additional", err}
}
}
- return msg, nil
+ return msg, compression, nil
}
// A Builder allows incrementally packing a DNS message.
diff --git a/dns/dnsmessage/message_test.go b/dns/dnsmessage/message_test.go
index 6c14576..b328d93 100644
--- a/dns/dnsmessage/message_test.go
+++ b/dns/dnsmessage/message_test.go
@@ -708,6 +708,60 @@ func BenchmarkBuilding(b *testing.B) {
}
}
+func BenchmarkName(b *testing.B) {
+ m := largeTestMsg()
+ msg, compression, err := m.pack()
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ benchmarks := []struct {
+ name string
+
+ comp map[string]int
+ msg []byte
+ }{
+ {"abc.xzy.", nil, nil},
+ {"ab.cde.fgh.ijk.lmn.opq.rst.uvw.xyz.", nil, nil},
+ {"example.com.", compression, msg},
+ {"bar.example.com.", compression, msg},
+ {"foo.bar.example.com.", compression, msg},
+ {"xyz.foo.bar.example.com.", compression, msg},
+ }
+
+ for _, bench := range benchmarks {
+ b.Run(bench.name, func(b *testing.B) {
+ b.ReportAllocs()
+
+ for i := 0; i < b.N; i++ {
+ comp := make(map[string]int, len(bench.comp))
+ for k, v := range bench.comp {
+ comp[k] = v
+ }
+
+ n1, err := NewName(bench.name)
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ buf, err := n1.pack(bench.msg, comp)
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ var n2 Name
+ if _, err = n2.unpack(buf, len(bench.msg)); err != nil {
+ b.Fatal(err)
+ }
+
+ if n2.String() != bench.name {
+ b.Fatalf("roundtrip failed")
+ }
+ }
+ })
+ }
+}
+
func largeTestMsg() Message {
return Message{
Header: Header{Response: true, Authoritative: true},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment