Skip to content

Instantly share code, notes, and snippets.

@aojea
Last active June 17, 2021 08:24
Show Gist options
  • Save aojea/d2176438dfc660b49bb71cc78f245d5e to your computer and use it in GitHub Desktop.
Save aojea/d2176438dfc660b49bb71cc78f245d5e to your computer and use it in GitHub Desktop.
Benchmark iterate a pod map by key or by value
Benchmark_Key-4            32955             36670 ns/op             109 B/op          0 allocs/op
Benchmark_Value-4          25776             47899 ns/op             140 B/op          0 allocs/op

It seems that by key requires is much better.

Also, it seems that the larger the size of the pod matters, I've tried with larger pods size and the results are worse for Value.

Most of the time is spent in runtime.duffcopy when iterating by value

package main
import (
"fmt"
"math/rand"
"testing"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func generatePods(n int) map[int]v1.Pod {
result := map[int]v1.Pod{}
fakeData := RandStringRunes(10000)
for i := 0; i < n; i++ {
result[i] = v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod%d", i),
Namespace: "testns",
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
{
Command: []string{"/bin/bash", "-c", "exec sleep 10000", fakeData},
Name: "hostexec",
Image: "centos:7",
ImagePullPolicy: v1.PullIfNotPresent,
},
},
HostNetwork: true,
},
}
}
return result
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
func IterateValue(pods map[int]v1.Pod) {
found := false
for _, pod := range pods {
if pod.Name == "hola" {
found = true
}
}
if found {
}
}
func IterateKey(pods map[int]v1.Pod) {
found := false
for i, _ := range pods {
if pods[i].Name == "hola" {
found = true
}
}
if found {
}
}
func Benchmark_Key(b *testing.B) {
pods := generatePods(1000)
for i := 0; i < b.N; i++ {
IterateKey(pods)
}
}
func Benchmark_Value(b *testing.B) {
pods := generatePods(1000)
for i := 0; i < b.N; i++ {
IterateValue(pods)
}
}
go test -benchmem -run=^$ -bench Benchmark_Key  -cpuprofile profile_key.out . -v
goos: linux
goarch: amd64
pkg: k8s.io/kubernetes
cpu: AMD Ryzen 3 3200G with Radeon Vega Graphics    
Benchmark_Key
Benchmark_Key-4            32955             36670 ns/op             109 B/op          0 allocs/op
PASS
ok      k8s.io/kubernetes       1.515s

go test -benchmem -run=^$ -bench Benchmark_Value  -cpuprofile profile_value.out . -v
goos: linux
goarch: amd64
pkg: k8s.io/kubernetes
cpu: AMD Ryzen 3 3200G with Radeon Vega Graphics    
Benchmark_Value
Benchmark_Value-4          25776             47899 ns/op             140 B/op          0 allocs/op
PASS
ok      k8s.io/kubernetes       1.934s
 go tool pprof profile_key.out 
File: kubernetes.test
Type: cpu
Time: Jun 17, 2021 at 9:56am (CEST)
Duration: 1.51s, Total samples = 1.41s (93.67%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1.39s, 98.58% of 1.41s total
Showing top 10 nodes out of 30
      flat  flat%   sum%        cum   cum%
     0.49s 34.75% 34.75%      1.35s 95.74%  k8s.io/kubernetes.IterateKey
     0.37s 26.24% 60.99%      0.57s 40.43%  runtime.mapaccess1
     0.21s 14.89% 75.89%      0.29s 20.57%  runtime.mapiternext
     0.10s  7.09% 82.98%      0.10s  7.09%  runtime.memequal64
     0.08s  5.67% 88.65%      0.08s  5.67%  runtime.memhash64
     0.05s  3.55% 92.20%      0.05s  3.55%  runtime.add (partial-inline)
     0.04s  2.84% 95.04%      0.04s  2.84%  runtime.isEmpty (inline)
     0.03s  2.13% 97.16%      0.03s  2.13%  runtime.suspendG
     0.01s  0.71% 97.87%      0.01s  0.71%  runtime.(*consistentHeapStats).acquire
     0.01s  0.71% 98.58%      0.01s  0.71%  runtime.bucketShift (inline)
     
     
     go tool pprof profile_value.out 
File: kubernetes.test
Type: cpu
Time: Jun 17, 2021 at 9:56am (CEST)
Duration: 1.92s, Total samples = 1.71s (88.98%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 1.71s, 100% of 1.71s total
Showing top 10 nodes out of 26
      flat  flat%   sum%        cum   cum%
     0.96s 56.14% 56.14%      0.96s 56.14%  runtime.duffcopy
     0.32s 18.71% 74.85%      1.67s 97.66%  k8s.io/kubernetes.IterateValue
     0.29s 16.96% 91.81%      0.39s 22.81%  runtime.mapiternext
     0.05s  2.92% 94.74%      0.05s  2.92%  runtime.add (partial-inline)
     0.03s  1.75% 96.49%      0.04s  2.34%  runtime.(*bmap).overflow
     0.02s  1.17% 97.66%      0.02s  1.17%  runtime.isEmpty (inline)
     0.01s  0.58% 98.25%      1.69s 98.83%  k8s.io/kubernetes.Benchmark_Value
     0.01s  0.58% 98.83%      0.01s  0.58%  runtime.(*mheap).freeMSpanLocked
     0.01s  0.58% 99.42%      0.01s  0.58%  runtime.mallocgc
     0.01s  0.58%   100%      0.01s  0.58%  runtime.markrootSpans
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment