'Is there an efficient way to calculate execution time in golang?
I'm looking for the best way to calculate execution time in go.
func main() {
start := time.Now()
time.Sleep(time.Second * 2)
//something doing here
elapsed := time.Since(start)
fmt.Printf("page took %s", elapsed)
}
The code above works fine.
But when I use templates, I have to write it again for each template function.
Is there an efficient way of calculating execution time, including templates?
Solution 1:[1]
If you are timing an entire function, then you can use defer
to eliminate some of the repetitive code.
func elapsed(what string) func() {
start := time.Now()
return func() {
fmt.Printf("%s took %v\n", what, time.Since(start))
}
}
func main() {
defer elapsed("page")() // <-- The trailing () is the deferred call
time.Sleep(time.Second * 2)
}
The specification says this about deferred calls:
Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns,
The function value elapsed("page")
is evaluated at the defer statement. The elapsed
function records the current time and returns an anonymous function. The returned anonymous function is invoked immediately before the surrounding function returns. The anonymous function computes and prints the elapsed time.
Solution 2:[2]
The solution provided by Bayta Darell is perfect.
In addition, if you don't want to pass function name explicitly, you could accomplish it like this:
func SomeFunction(list *[]string) {
defer TimeTrack(time.Now())
// Do whatever you want.
}
func TimeTrack(start time.Time) {
elapsed := time.Since(start)
// Skip this function, and fetch the PC and file for its parent.
pc, _, _, _ := runtime.Caller(1)
// Retrieve a function object this functions parent.
funcObj := runtime.FuncForPC(pc)
// Regex to extract just the function name (and not the module path).
runtimeFunc := regexp.MustCompile(`^.*\.(.*)$`)
name := runtimeFunc.ReplaceAllString(funcObj.Name(), "$1")
log.Println(fmt.Sprintf("%s took %s", name, elapsed))
}
As a result, you would get:
SomeFunction took 15.483µs
For more information, Refer this article: Go Function Tracing
Share the knowledge. :)
Solution 3:[3]
Use init function
package main
import (
"fmt"
"time"
)
var start time.Time
func init() {
start = time.Now()
}
func getChars(s string) {
for _, c := range s {
fmt.Printf("%c at time %v\n", c, time.Since(start))
time.Sleep(10 * time.Millisecond)
}
}
func main() {
fmt.Println("main execution started at time", time.Since(start))
getChars("Hello")
fmt.Println("\nmain execution stopped at time", time.Since(start))
}
Solution 4:[4]
Efficient way to calculate execution time in golang
You can easily get the execution time on your console using a defer function
defer functions execute even if the code get an error so you always get the execution time.
time package is used to get the time difference.
func main() {
now := time.Now()
defer func() {
fmt.Println(time.Now().Sub(now))
}()
// Here you can do whatever you want
}
Or you can use this code
func main() {
now := time.Now()
defer func() {
fmt.Println(time.Since(now))
}()
// Here you can do whatever you want
}
check the code in Playground for more. I added some functionality to recover from an error at the same time print the execution time, even if in the case of a panic error.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Shiva |
Solution 3 | Uday Hiwarale |
Solution 4 | Community |