[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} <nil>

real    0m0.019s
user    0m0.008s
sys     0m0.013s
{load1:0.8876953125,load5:0.98828125,load15:1.0146484375} <nil>

real    0m0.011s
user    0m0.004s
sys     0m0.006s

This is faster and yields more precise results.
pull/644/head
Lomanic 6 years ago
parent 2ec35609d2
commit 974d52d412

@ -5,10 +5,10 @@ package load
import ( import (
"context" "context"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common" "golang.org/x/sys/unix"
) )
func Avg() (*AvgStat, error) { func Avg() (*AvgStat, error) {
@ -16,28 +16,23 @@ func Avg() (*AvgStat, error) {
} }
func AvgWithContext(ctx context.Context) (*AvgStat, error) { func AvgWithContext(ctx context.Context) (*AvgStat, error) {
values, err := common.DoSysctrlWithContext(ctx, "vm.loadavg") // This SysctlRaw method borrowed from
if err != nil { // https://github.com/prometheus/node_exporter/blob/master/collector/loadavg_freebsd.go
return nil, err // this implementation is common with BSDs
} type loadavg struct {
load [3]uint32
load1, err := strconv.ParseFloat(values[0], 64) scale int
if err != nil {
return nil, err
} }
load5, err := strconv.ParseFloat(values[1], 64) b, err := unix.SysctlRaw("vm.loadavg")
if err != nil { if err != nil {
return nil, err return nil, err
} }
load15, err := strconv.ParseFloat(values[2], 64) load := *(*loadavg)(unsafe.Pointer((&b[0])))
if err != nil { scale := float64(load.scale)
return nil, err
}
ret := &AvgStat{ ret := &AvgStat{
Load1: float64(load1), Load1: float64(load.load[0]) / scale,
Load5: float64(load5), Load5: float64(load.load[1]) / scale,
Load15: float64(load15), Load15: float64(load.load[2]) / scale,
} }
return ret, nil return ret, nil

Loading…
Cancel
Save