package main import ( "fmt" "log" "os" "os/exec" "strconv" "strings" "time" "github.com/shirou/gopsutil/process" ) func main() { max, err := strconv.Atoi(os.Args[1]) if err != nil { panic(err) } var cpuAvg float64 fmt.Print("Forking ") for i := 0; i < (max/10 - 8); i++ { fmt.Print("#") } fmt.Println() start := time.Now() for ctr := 1; ctr < max; ctr++ { getProcsForking() cpuAvg = ravg(cpuAvg, ctr) if (ctr % 10) == 0 { if (ctr % 50) == 0 { fmt.Print("X") } else { fmt.Print(".") } } } end := time.Now() fmt.Printf("\nAverage CPU: %d\nTime: %v\n", int(cpuAvg*100.0), end.Sub(start)) cpuAvg = 0.0 fmt.Print("GoPsUtil ") for i := 0; i < (max/10 - 9); i++ { fmt.Print("#") } fmt.Println() start = time.Now() for ctr := 1; ctr < max; ctr++ { getProcsGoPsUtil() cpuAvg = ravg(cpuAvg, ctr) if (ctr % 10) == 0 { if (ctr % 50) == 0 { fmt.Print("X") } else { fmt.Print(".") } } } end = time.Now() fmt.Printf("\nAverage CPU: %d\nTime: %v\n", int(cpuAvg*100.0), end.Sub(start)) } type D struct { p int32 c float64 m float32 } func ravg(o float64, n int) float64 { v, e := getCpuUse() if e != nil { panic(e) } nf := float64(n) na := o*((nf-1.0)/nf) + v/nf return na } func getCpuUse() (float64, error) { me := os.Getpid() p, e := process.NewProcess(int32(me)) if e != nil { return 0.0, e } return p.CPUPercent() } func getProcsForking() ([]D, error) { output, err := exec.Command("ps", "-axo", "pid:10,comm:50,pcpu:5,pmem:5,args").Output() if err != nil { return []D{}, fmt.Errorf("failed to execute 'ps' command: %v", err) } // converts to []string, removing trailing newline and header linesOfProcStrings := strings.Split(strings.TrimSuffix(string(output), "\n"), "\n")[1:] rvs := make([]D, len(linesOfProcStrings)) for i, line := range linesOfProcStrings { pid, err := strconv.Atoi(strings.TrimSpace(line[0:10])) if err != nil { log.Printf("failed to convert PID to int: %v. line: %v", err, line) } cpu, err := strconv.ParseFloat(strings.TrimSpace(line[63:68]), 64) if err != nil { log.Printf("failed to convert CPU usage to float: %v. line: %v", err, line) } mem, err := strconv.ParseFloat(strings.TrimSpace(line[69:74]), 32) if err != nil { log.Printf("failed to convert Mem usage to float: %v. line: %v", err, line) } rvs[i] = D{p: int32(pid), c: cpu, m: float32(mem)} } return rvs, nil } func getProcsGoPsUtil() ([]D, error) { procs, err := process.Processes() if err != nil { return nil, err } rvs := make([]D, len(procs)) for i, p := range procs { cpu, err := p.CPUPercent() if err != nil { return nil, err } mem, err := p.MemoryPercent() rvs[i] = D{p: p.Pid, c: cpu, m: mem} } return rvs, nil }