[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.
This commit is contained in:
Lomanic 2019-03-02 18:47:41 +01:00
parent 2ec35609d2
commit 974d52d412
1 changed files with 15 additions and 20 deletions

View File

@ -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