Created
February 2, 2026 14:31
-
-
Save florianl/c556d153d90441f51fe5e5b607312215 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bytes" | |
| "fmt" | |
| "regexp" | |
| "strconv" | |
| "strings" | |
| "testing" | |
| "go.opentelemetry.io/ebpf-profiler/libpf" | |
| "go.opentelemetry.io/ebpf-profiler/libpf/pfunsafe" | |
| ) | |
| // Old implementation (cgroup v2 only) | |
| var cgroupv2ContainerIDPattern = regexp.MustCompile(`0:.*?:.*?([0-9a-fA-F]{64})(?:\.scope)?(?:/[a-z]+)?$`) | |
| func parseContainerIDOld(cgroupData []byte) libpf.String { | |
| lines := bytes.Split(cgroupData, []byte("\n")) | |
| for _, line := range lines { | |
| if bytes.Equal(line, []byte("0::/")) { | |
| continue | |
| } | |
| pathParts := cgroupv2ContainerIDPattern.FindSubmatch(line) | |
| if pathParts != nil { | |
| return libpf.Intern(string(pathParts[1])) | |
| } | |
| } | |
| return libpf.NullString | |
| } | |
| // New implementation (cgroup v1 and v2) | |
| const ( | |
| containerSourceBench = "[0-9a-f]{64}" | |
| taskSourceBench = "[0-9a-f]{32}-\\d+" | |
| ) | |
| var expContainerIDBench = regexp.MustCompile(fmt.Sprintf(`(%s|%s)(?:\.scope)?(?:/[a-z]+)?$`, containerSourceBench, taskSourceBench)) | |
| func parseContainerIDNew(cgroupData []byte) libpf.String { | |
| lines := bytes.Split(cgroupData, []byte("\n")) | |
| for _, b := range lines { | |
| if bytes.Equal(b, []byte("0::/")) { | |
| continue | |
| } | |
| line := pfunsafe.ToString(b) | |
| parts := strings.SplitN(line, ":", 3) | |
| _, err := strconv.Atoi(parts[0]) | |
| if len(parts) == 3 && err == nil { | |
| sub := parts[2] | |
| if partsIdx := expContainerIDBench.FindStringSubmatchIndex(sub); len(partsIdx) == 4 { | |
| return libpf.Intern(sub[partsIdx[2]:partsIdx[3]]) | |
| } | |
| } | |
| } | |
| return libpf.NullString | |
| } | |
| // Test data representing various cgroup formats | |
| var testCases = []struct { | |
| name string | |
| data []byte | |
| }{ | |
| { | |
| name: "cgroupv2_kubernetes_containerd", | |
| data: []byte("0::/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf6f2d169_f2ae_4afa-95ed_06ff2ed6b288.slice/cri-containerd-b4d6d161c62525d726fa394b27df30e14f8ea5646313ada576b390de70cfc8cc.scope\n"), | |
| }, | |
| { | |
| name: "cgroupv2_docker", | |
| data: []byte("0::/system.slice/docker-b1eba9dfaeba29d8b80532a574a03ea3cac29384327f339c26da13649e2120df.scope\n"), | |
| }, | |
| { | |
| name: "cgroupv1_kubernetes_memory", | |
| data: []byte("11:memory:/kubepods/besteffort/poda9c80282-3f6b-4d5b-84d5-a137a6668011/ed89697807a981b82f6245ac3a13be232c1e13435d52bc3f53060d61babe1997\n"), | |
| }, | |
| { | |
| name: "cgroupv1_kubernetes_cpu", | |
| data: []byte("11:cpucpuacct:/system.slice/containerd.service/kubepods-besteffort-pod86811ae3_b633_4eb8_a508_e3eae190f6ce.slice:cri-containerd:da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a\n"), | |
| }, | |
| { | |
| name: "cgroupv1_systemd", | |
| data: []byte("1:name=systemd:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf6f2d169_f2ae_4afa_95ed_06ff2ed6b288.slice/cri-containerd-b4d6d161c62525d726fa394b27df30e14f8ea5646313ada576b390de70cfc8cc.scope\n"), | |
| }, | |
| { | |
| name: "cgroupv2_multiple_lines", | |
| data: []byte(`0::/ | |
| 0::/system.slice/docker-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2.scope | |
| `), | |
| }, | |
| { | |
| name: "cgroupv1_multiple_hierarchies", | |
| data: []byte(`12:perf_event:/kubepods/besteffort/pod123/container456 | |
| 11:memory:/kubepods/besteffort/poda9c80282-3f6b-4d5b-84d5-a137a6668011/ed89697807a981b82f6245ac3a13be232c1e13435d52bc3f53060d61babe1997 | |
| 10:devices:/kubepods/besteffort/pod123/container456 | |
| `), | |
| }, | |
| { | |
| name: "no_container", | |
| data: []byte("0::/user.slice/user-1000.slice/user@1000.service\n"), | |
| }, | |
| } | |
| // Benchmark old implementation (cgroup v2 only) | |
| func BenchmarkParseContainerID_Old(b *testing.B) { | |
| for _, tc := range testCases { | |
| b.Run(tc.name, func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDOld(tc.data) | |
| } | |
| }) | |
| } | |
| } | |
| // Benchmark new implementation (cgroup v1 and v2) | |
| func BenchmarkParseContainerID_New(b *testing.B) { | |
| for _, tc := range testCases { | |
| b.Run(tc.name, func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDNew(tc.data) | |
| } | |
| }) | |
| } | |
| } | |
| // Comparison benchmark - measures percentage difference | |
| func BenchmarkParseContainerID_Comparison(b *testing.B) { | |
| b.Run("Old_vs_New_AllCases", func(b *testing.B) { | |
| b.Run("Old", func(b *testing.B) { | |
| b.ReportAllocs() | |
| for i := 0; i < b.N; i++ { | |
| for _, tc := range testCases { | |
| _ = parseContainerIDOld(tc.data) | |
| } | |
| } | |
| }) | |
| b.Run("New", func(b *testing.B) { | |
| b.ReportAllocs() | |
| for i := 0; i < b.N; i++ { | |
| for _, tc := range testCases { | |
| _ = parseContainerIDNew(tc.data) | |
| } | |
| } | |
| }) | |
| }) | |
| } | |
| // Benchmark with realistic multi-line cgroup files | |
| func BenchmarkParseContainerID_Realistic(b *testing.B) { | |
| // Realistic cgroup v1 file with multiple controller hierarchies | |
| cgroupv1Data := []byte(`12:perf_event:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 11:memory:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 10:devices:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 9:hugetlb:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 8:blkio:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 7:freezer:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 6:cpuset:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 5:net_cls,net_prio:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 4:pids:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 3:cpu,cpuacct:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| 2:rdma:/ | |
| 1:name=systemd:/kubepods/besteffort/pod86811ae3-b633-4eb8-a508-e3eae190f6ce/da1bdd84c8b25938081afe48da7075e2a211d2b1a62e01c894b4e5f3ffab670a | |
| `) | |
| // Realistic cgroup v2 file (unified hierarchy) | |
| cgroupv2Data := []byte(`0::/system.slice/docker-b4d6d161c62525d726fa394b27df30e14f8ea5646313ada576b390de70cfc8cc.scope | |
| `) | |
| b.Run("Realistic_cgroupv1", func(b *testing.B) { | |
| b.Run("Old", func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDOld(cgroupv1Data) | |
| } | |
| }) | |
| b.Run("New", func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDNew(cgroupv1Data) | |
| } | |
| }) | |
| }) | |
| b.Run("Realistic_cgroupv2", func(b *testing.B) { | |
| b.Run("Old", func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDOld(cgroupv2Data) | |
| } | |
| }) | |
| b.Run("New", func(b *testing.B) { | |
| b.ReportAllocs() | |
| b.ResetTimer() | |
| for i := 0; i < b.N; i++ { | |
| _ = parseContainerIDNew(cgroupv2Data) | |
| } | |
| }) | |
| }) | |
| } | |
| // Benchmark regex compilation impact (one-time cost) | |
| func BenchmarkRegexCompilation(b *testing.B) { | |
| b.Run("Old_Pattern", func(b *testing.B) { | |
| for i := 0; i < b.N; i++ { | |
| _ = regexp.MustCompile(`0:.*?:.*?([0-9a-fA-F]{64})(?:\.scope)?(?:/[a-z]+)?$`) | |
| } | |
| }) | |
| b.Run("New_Pattern", func(b *testing.B) { | |
| for i := 0; i < b.N; i++ { | |
| _ = regexp.MustCompile(fmt.Sprintf(`(%s|%s)(?:\.scope)?(?:/[a-z]+)?$`, containerSourceBench, taskSourceBench)) | |
| } | |
| }) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $ go test -bench=. | |
| goos: linux | |
| goarch: amd64 | |
| pkg: 1173 | |
| cpu: 12th Gen Intel(R) Core(TM) i7-12700H | |
| BenchmarkParseContainerID_Old/cgroupv2_kubernetes_containerd-20 328604 3596 ns/op 161 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv2_docker-20 1266465 954.4 ns/op 160 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv1_kubernetes_memory-20 12299006 93.41 ns/op 48 B/op 1 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv1_kubernetes_cpu-20 11435577 105.6 ns/op 48 B/op 1 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv1_systemd-20 11551842 103.0 ns/op 48 B/op 1 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv2_multiple_lines-20 1239174 954.7 ns/op 192 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Old/cgroupv1_multiple_hierarchies-20 9836048 113.5 ns/op 96 B/op 1 allocs/op | |
| BenchmarkParseContainerID_Old/no_container-20 32114302 36.27 ns/op 48 B/op 1 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv2_kubernetes_containerd-20 195297 5624 ns/op 128 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv2_docker-20 1000000 1131 ns/op 128 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv1_kubernetes_memory-20 326467 3462 ns/op 128 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv1_kubernetes_cpu-20 202774 5433 ns/op 128 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv1_systemd-20 193164 5537 ns/op 128 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv2_multiple_lines-20 998610 1167 ns/op 160 B/op 3 allocs/op | |
| BenchmarkParseContainerID_New/cgroupv1_multiple_hierarchies-20 227343 5062 ns/op 225 B/op 4 allocs/op | |
| BenchmarkParseContainerID_New/no_container-20 713857 1632 ns/op 160 B/op 4 allocs/op | |
| BenchmarkParseContainerID_Comparison/Old_vs_New_AllCases/Old-20 179330 6101 ns/op 803 B/op 14 allocs/op | |
| BenchmarkParseContainerID_Comparison/Old_vs_New_AllCases/New-20 41179 29348 ns/op 1190 B/op 26 allocs/op | |
| BenchmarkParseContainerID_Realistic/Realistic_cgroupv1/Old-20 446925 2731 ns/op 433 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Realistic/Realistic_cgroupv1/New-20 327992 3714 ns/op 401 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Realistic/Realistic_cgroupv2/Old-20 1282798 923.7 ns/op 160 B/op 3 allocs/op | |
| BenchmarkParseContainerID_Realistic/Realistic_cgroupv2/New-20 918933 1135 ns/op 128 B/op 3 allocs/op | |
| BenchmarkRegexCompilation/Old_Pattern-20 163942 7281 ns/op | |
| BenchmarkRegexCompilation/New_Pattern-20 174321 8145 ns/op | |
| PASS | |
| ok 1173 33.048s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment