Skip to content

Instantly share code, notes, and snippets.

@cpuschma
Last active April 8, 2021 19:17
Show Gist options
  • Save cpuschma/e4faf1a90bb610e59ec622e3e6e62558 to your computer and use it in GitHub Desktop.
Save cpuschma/e4faf1a90bb610e59ec622e3e6e62558 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"testing"
)
/*
goos: windows
goarch: amd64
cpu: Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz
Benchmark_unpackAttributesOld/1_attributes-4 918266 1103 ns/op 392 B/op 12 allocs/op
Benchmark_unpackAttributesOld/2_attributes-4 545382 2216 ns/op 792 B/op 23 allocs/op
Benchmark_unpackAttributesOld/4_attributes-4 279080 4316 ns/op 1592 B/op 44 allocs/op
Benchmark_unpackAttributesOld/8_attributes-4 140222 8420 ns/op 3192 B/op 85 allocs/op
Benchmark_unpackAttributesOld/16_attributes-4 69276 16431 ns/op 6392 B/op 166 allocs/op
Benchmark_unpackAttributesOld/32_attributes-4 37326 32347 ns/op 12792 B/op 327 allocs/op
Benchmark_unpackAttributesOld/64_attributes-4 18651 64221 ns/op 25593 B/op 648 allocs/op
Benchmark_unpackAttributes/2_attributes-4 1000000 1234 ns/op 608 B/op 13 allocs/op
Benchmark_unpackAttributes/4_attributes-4 488536 2356 ns/op 1216 B/op 25 allocs/op
Benchmark_unpackAttributes/8_attributes-4 256641 4602 ns/op 2432 B/op 49 allocs/op
Benchmark_unpackAttributes/16_attributes-4 129054 9209 ns/op 4864 B/op 97 allocs/op
Benchmark_unpackAttributes/32_attributes-4 65010 18537 ns/op 9728 B/op 193 allocs/op
Benchmark_unpackAttributes/64_attributes-4 32641 36662 ns/op 19456 B/op 385 allocs/op
*/
type Entry struct {
DN string
Attributes []*EntryAttribute
}
type EntryAttribute struct {
Name string
Values []string
ByteValues [][]byte
}
type fakePacket struct {
Children []*fakePacket
Value interface{}
ByteValue []byte
}
var (
packet = &fakePacket{
Children: []*fakePacket{
{
Children: []*fakePacket{
{
Value: "attribute1",
},
{
Children: []*fakePacket{
{
Value: "val1",
ByteValue: []byte("val1"),
},
{
Value: "val2",
ByteValue: []byte("val2"),
},
},
},
},
},
},
}
)
func Benchmark_unpackAttributesOld(b *testing.B) {
for i := 1; i <= 7; i++ {
b.Run(fmt.Sprintf("%d attributes", len(packet.Children)), func(b *testing.B) {
b.StopTimer()
// reset attributes to one
packet.Children = packet.Children[:1]
for a := 1; a <= i; a++ {
packet.Children = append(packet.Children, packet.Children...)
}
b.StartTimer()
for i := 0; i <= b.N; i++ {
_ = Entry{
DN: "cn=test,dc=example,dc=com",
Attributes: unpackAttributesOld(packet.Children),
}
}
})
}
}
func Benchmark_unpackAttributes(b *testing.B) {
for i := 1; i <= 7; i++ {
b.Run(fmt.Sprintf("%d attributes", len(packet.Children)), func(b *testing.B) {
b.StopTimer()
// reset attributes to one
packet.Children = packet.Children[:1]
for a := 1; a <= i; a++ {
packet.Children = append(packet.Children, packet.Children...)
}
b.StartTimer()
for i := 0; i <= b.N; i++ {
_ = Entry{
DN: "cn=test,dc=example,dc=com",
Attributes: unpackAttributes(packet.Children),
}
}
})
}
}
func unpackAttributesOld(children []*fakePacket) []*EntryAttribute {
var attributes []*EntryAttribute
for _, child := range children {
attr := new(EntryAttribute)
attr.Name = child.Children[0].Value.(string)
for _, value := range child.Children[1].Children {
attr.Values = append(attr.Values, value.Value.(string))
attr.ByteValues = append(attr.ByteValues, value.ByteValue)
}
attributes = append(attributes, attr)
}
return attributes
}
func unpackAttributes(children []*fakePacket) []*EntryAttribute {
entries := make([]*EntryAttribute, len(children))
for i, child := range children {
length := len(child.Children[1].Children)
entry := &EntryAttribute{
Name: child.Children[0].Value.(string),
// pre-allocate the slice since we can determine
// the number of attributes at this point
Values: make([]string, length),
ByteValues: make([][]byte, length),
}
for i, value := range child.Children[1].Children {
entry.ByteValues[i] = value.ByteValue
entry.Values[i] = value.Value.(string)
}
entries[i] = entry
}
return entries
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment