I want to build a benchmarking tool similar to the unix tool time
. What I currently have is this:
package main
import (
"fmt"
"os"
"os/exec"
"time"
)
func main() {
command := os.Args[1]
args := os.Args[2:]
cmd := exec.Command(command, args...)
start_time := time.Now().UnixNano()
stdout, err := cmd.Output()
if err != nil {
println(err.Error())
return
}
print(string(stdout))
total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)
fmt.Println(total_time)
}
My problem with this is, that the output is not streaming, instead it is printed all at once, and weirdly enough for some programs not at all.
The best way is to avoid touching the stream altogether. You can pass your own file descriptors for stdout and stderr directly.
package main
import (
"fmt"
"os"
"os/exec"
"time"
)
func main() {
command := os.Args[1]
args := os.Args[2:]
cmd := exec.Command(command, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
start_time := time.Now()
err := cmd.Run()
if err != nil {
println(err.Error())
return
}
total_time := int64(time.Since(start_time) / time.Millisecond)
fmt.Println(total_time)
}
Also, print() should never be used. Instead, use one of the fmt.Print* functions.
total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)
This line is extremely confusing. int64(time.Nanosecond) * x
resolves to 1 * x
or just x
.
I'm not sure what you're attempting to do here with print(string(stdout))
but it's unnecessary and the problems you're facing are likely a side effect of some misuse there.
func main() {
command := os.Args[1]
args := os.Args[2:]
cmd := exec.Command(command, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
start_time := time.Now().UnixNano()
if err != nil {
fmt.Println(err.Error())
return
}
total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)
fmt.Println(total_time)
}