How to Measure Function Execution Time in Go
When tracking the performance of a Go function, it's common to use the defer statement to defer the execution of a function until the surrounding function returns. However, in certain cases, deferring the execution of a function to print its execution time may result in an unexpected zero-value output.
Consider the following code:
func sum() { start := time.Now() //expecting to print non zero value but always gets 0 defer fmt.Println(time.Now().Sub(start)) sum := 0 for i := 1; i < 101; i++ { sum += i } time.Sleep(1 * time.Second) fmt.Println(sum) }
In this example, the defer statement is attempting to print the elapsed time since the function was initially called. However, because the arguments to the deferred function are evaluated at the point the function is deferred, the time.Now() call is made immediately when start is assigned, resulting in a start time that does not reflect the actual time taken to execute the function.
To address this issue, the code can be modified as follows:
defer func() { fmt.Println(time.Now().Sub(start)) }()
By wrapping the fmt.Println call in an anonymous function, the arguments to the deferred function are evaluated when the function is executed, ensuring that the start time is captured correctly.
Additionally, using a reusable function to encapsulate the timing logic can further simplify the code:
func timeFunction(f func()) { start := time.Now() f() fmt.Println(time.Now().Sub(start)) }
This function can then be used as follows:
timeFunction(func() { sum := 0 for i := 1; i < 101; i++ { sum += i } time.Sleep(1 * time.Second) fmt.Println(sum) })
By understanding how deferred functions work in Go, developers can effectively measure the execution time of functions and optimize their performance.
The above is the detailed content of Why does measuring function execution time with `defer` in Go sometimes return zero?. For more information, please follow other related articles on the PHP Chinese website!