Skip to content

Commit d0c3bc4

Browse files
committed
libct/cg: GetAllPids: optimize for go 1.16+
filepath.WalkDir function, introduced in Go 1.16, doesn't do stat(2) on every entry, and is therefore somewhat faster (see below). Since we have to support Go 1.15, keep the old version for backward compatibility. Add a quick benchmark, which shows approximately 3x improvement: $ go1.15.15 test -bench AllPid -run xxx . BenchmarkGetAllPids-4 48 23528839 ns/op $ go version go version go1.16.6 linux/amd64 $ go test -bench AllPid -run xxx . BenchmarkGetAllPids-4 147 7700170 ns/op (Unrelated but worth noting -- go 1.17rc2 is pushing it even further) $ go1.17rc2 test -bench AllPid -run xxx . BenchmarkGetAllPids-4 164 6820994 ns/op Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 363468d commit d0c3bc4

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

libcontainer/cgroups/getallpids.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
// +build linux
1+
// +build linux,go1.16
22

33
package cgroups
44

55
import (
6-
"os"
6+
"io/fs"
77
"path/filepath"
88
)
99

10-
// GetAllPids returns all pids, that were added to cgroup at path and to all its
11-
// subcgroups.
10+
// GetAllPids returns all pids from the cgroup identified by path, and all its
11+
// sub-cgroups.
1212
func GetAllPids(path string) ([]int, error) {
1313
var pids []int
14-
// collect pids from all sub-cgroups
15-
err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
14+
err := filepath.WalkDir(path, func(p string, d fs.DirEntry, iErr error) error {
1615
if iErr != nil {
1716
return iErr
1817
}
19-
if !info.IsDir() {
18+
if !d.IsDir() {
2019
return nil
2120
}
2221
cPids, err := readProcsFile(p)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// +build linux,!go1.16
2+
3+
package cgroups
4+
5+
import (
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
// GetAllPids returns all pids, that were added to cgroup at path and to all its
11+
// subcgroups.
12+
func GetAllPids(path string) ([]int, error) {
13+
var pids []int
14+
// collect pids from all sub-cgroups
15+
err := filepath.Walk(path, func(p string, info os.FileInfo, iErr error) error {
16+
if iErr != nil {
17+
return iErr
18+
}
19+
if !info.IsDir() {
20+
return nil
21+
}
22+
cPids, err := readProcsFile(p)
23+
if err != nil {
24+
return err
25+
}
26+
pids = append(pids, cPids...)
27+
return nil
28+
})
29+
return pids, err
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// +build linux
2+
3+
package cgroups
4+
5+
import (
6+
"testing"
7+
)
8+
9+
func BenchmarkGetAllPids(b *testing.B) {
10+
total := 0
11+
for i := 0; i < b.N; i++ {
12+
i, err := GetAllPids("/sys/fs/cgroup")
13+
if err != nil {
14+
b.Fatal(err)
15+
}
16+
total += len(i)
17+
}
18+
b.Logf("iter: %d, total: %d", b.N, total)
19+
}

0 commit comments

Comments
 (0)