From 974d52d4121dd14eb7dc5fa4169868d6a8b2c330 Mon Sep 17 00:00:00 2001 From: Lomanic Date: Sat, 2 Mar 2019 18:47:41 +0100 Subject: [PATCH] [load][darwin] Remove calls to sysctl binary in load/load_darwin.go #639 Again, a simple benchmark: Lomanics-iMac:~ lomanic$ time ./load_avg.old ; time ./load_avg {load1:0.89,load5:0.99,load15:1.01} real 0m0.019s user 0m0.008s sys 0m0.013s {load1:0.8876953125,load5:0.98828125,load15:1.0146484375} real 0m0.011s user 0m0.004s sys 0m0.006s This is faster and yields more precise results. --- load/load_darwin.go | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/load/load_darwin.go b/load/load_darwin.go index cd7b74d..a205f2f 100644 --- a/load/load_darwin.go +++ b/load/load_darwin.go @@ -5,10 +5,10 @@ package load import ( "context" "os/exec" - "strconv" "strings" + "unsafe" - "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" ) func Avg() (*AvgStat, error) { @@ -16,28 +16,23 @@ func Avg() (*AvgStat, error) { } func AvgWithContext(ctx context.Context) (*AvgStat, error) { - values, err := common.DoSysctrlWithContext(ctx, "vm.loadavg") + // This SysctlRaw method borrowed from + // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go + // this implementation is common with BSDs + type loadavg struct { + load [3]uint32 + scale int + } + b, err := unix.SysctlRaw("vm.loadavg") if err != nil { return nil, err } - - load1, err := strconv.ParseFloat(values[0], 64) - if err != nil { - return nil, err - } - load5, err := strconv.ParseFloat(values[1], 64) - if err != nil { - return nil, err - } - load15, err := strconv.ParseFloat(values[2], 64) - if err != nil { - return nil, err - } - + load := *(*loadavg)(unsafe.Pointer((&b[0]))) + scale := float64(load.scale) ret := &AvgStat{ - Load1: float64(load1), - Load5: float64(load5), - Load15: float64(load15), + Load1: float64(load.load[0]) / scale, + Load5: float64(load.load[1]) / scale, + Load15: float64(load.load[2]) / scale, } return ret, nil