mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
libct/cg/dev: optimize and test findDeviceGroup
1. Use strings.TrimPrefix instead of fmt.Sscanf and simplify the code. 2. Add a test case and a benchmark. The benchmark shows some improvement, compared to the old implementation: name old time/op new time/op delta FindDeviceGroup-4 39.7µs ± 2% 26.8µs ± 2% -32.63% (p=0.008 n=5+5) name old alloc/op new alloc/op delta FindDeviceGroup-4 6.08kB ± 0% 4.23kB ± 0% -30.39% (p=0.008 n=5+5) name old allocs/op new allocs/op delta FindDeviceGroup-4 117 ± 0% 6 ± 0% -94.87% (p=0.008 n=5+5) Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -2,9 +2,9 @@ package devices
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
systemdDbus "github.com/coreos/go-systemd/v22/dbus"
|
||||||
@@ -181,6 +181,7 @@ func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
ruleMajorStr := strconv.FormatInt(ruleMajor, 10) + " "
|
||||||
|
|
||||||
scanner := bufio.NewScanner(fh)
|
scanner := bufio.NewScanner(fh)
|
||||||
var currentType devices.Type
|
var currentType devices.Type
|
||||||
@@ -205,20 +206,9 @@ func findDeviceGroup(ruleType devices.Type, ruleMajor int64) (string, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse out the (major, name).
|
group := strings.TrimPrefix(line, ruleMajorStr)
|
||||||
var (
|
if len(group) < len(line) { // got it
|
||||||
currMajor int64
|
return prefix + group, nil
|
||||||
currName string
|
|
||||||
)
|
|
||||||
if n, err := fmt.Sscanf(line, "%d %s", &currMajor, &currName); err != nil || n != 2 {
|
|
||||||
if err == nil {
|
|
||||||
err = errors.New("wrong number of fields")
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("scan /proc/devices line %q: %w", line, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if currMajor == ruleMajor {
|
|
||||||
return prefix + currName, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package devices
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -240,6 +241,32 @@ func TestSkipDevicesFalse(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testFindDeviceGroup() error {
|
||||||
|
const (
|
||||||
|
major = 136
|
||||||
|
group = "char-pts"
|
||||||
|
)
|
||||||
|
res, err := findDeviceGroup(devices.CharDevice, major)
|
||||||
|
if res != group || err != nil {
|
||||||
|
return fmt.Errorf("expected %v, nil, got %v, %w", group, res, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindDeviceGroup(t *testing.T) {
|
||||||
|
if err := testFindDeviceGroup(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkFindDeviceGroup(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if err := testFindDeviceGroup(); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newManager(t *testing.T, config *configs.Cgroup) (m cgroups.Manager) {
|
func newManager(t *testing.T, config *configs.Cgroup) (m cgroups.Manager) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
Reference in New Issue
Block a user