diff --git a/proc_maps.go b/proc_maps.go index 727549a1..7e75c286 100644 --- a/proc_maps.go +++ b/proc_maps.go @@ -63,17 +63,17 @@ type ProcMap struct { // parseDevice parses the device token of a line and converts it to a dev_t // (mkdev) like structure. func parseDevice(s string) (uint64, error) { - toks := strings.Split(s, ":") - if len(toks) < 2 { - return 0, fmt.Errorf("%w: unexpected number of fields, expected: 2, got: %q", ErrFileParse, len(toks)) + i := strings.Index(s, ":") + if i == -1 { + return 0, fmt.Errorf("%w: expected separator `:` in %s", ErrFileParse, s) } - major, err := strconv.ParseUint(toks[0], 16, 0) + major, err := strconv.ParseUint(s[0:i], 16, 0) if err != nil { return 0, err } - minor, err := strconv.ParseUint(toks[1], 16, 0) + minor, err := strconv.ParseUint(s[i+1:], 16, 0) if err != nil { return 0, err } @@ -93,17 +93,17 @@ func parseAddress(s string) (uintptr, error) { // parseAddresses parses the start-end address. func parseAddresses(s string) (uintptr, uintptr, error) { - toks := strings.Split(s, "-") - if len(toks) < 2 { - return 0, 0, fmt.Errorf("%w: invalid address", ErrFileParse) + idx := strings.Index(s, "-") + if idx == -1 { + return 0, 0, fmt.Errorf("%w: expected separator `-` in %s", ErrFileParse, s) } - saddr, err := parseAddress(toks[0]) + saddr, err := parseAddress(s[0:idx]) if err != nil { return 0, 0, err } - eaddr, err := parseAddress(toks[1]) + eaddr, err := parseAddress(s[idx+1:]) if err != nil { return 0, 0, err } diff --git a/proc_maps64_test.go b/proc_maps64_test.go index 66ef1349..44ec68c4 100644 --- a/proc_maps64_test.go +++ b/proc_maps64_test.go @@ -138,3 +138,40 @@ func TestProcMaps(t *testing.T) { } } + +var start, end uintptr + +func BenchmarkParseAddress(b *testing.B) { + b.ReportAllocs() + var ( + s, e uintptr + err error + ) + for i := 0; i < b.N; i++ { + s, e, err = parseAddresses("7f7d7469e000-7f7d746a0000") + if err != nil { + b.Fatal(err) + } + } + // Prevent the compiler from optimizing away benchmark code. + start = s + end = e +} + +var device uint64 + +func BenchmarkParseDevice(b *testing.B) { + b.ReportAllocs() + var ( + d uint64 + err error + ) + for i := 0; i < b.N; i++ { + d, err = parseDevice("00:22") + if err != nil { + b.Fatal(err) + } + } + // Prevent the compiler from optimizing away benchmark code. + device = d +}