Is there a difference (in the context of performance) between the three implementations below?:
mustGetSpeed := func() string {
...
return speed
}
for _, item := range items {
speed, err := strconv.Atoi(mustGetSpeed())
...
}
for _, item := range items {
mustGetSpeed := func() string {
...
return speed
}
speed, err := strconv.Atoi(mustGetSpeed())
...
}
for _, item := range items {
speed, err := strconv.Atoi(func() string {
...
return speed
}())
...
}
Is it a mistake (in the context of performance) declares closure into a loop?
You are speculating about a performance question. Don't do that. Get some facts. Run some benchmarks. For example,
package main
import (
"strconv"
"testing"
)
const sound = "1236" // speed of sound 1,236 kilometres per hour
var items = make([]int, 1024)
func BenchmarkClosure1(b *testing.B) {
for i := 0; i < b.N; i++ {
mustGetSpeed := func() string {
speed := sound
// ...
return speed
}
for _, item := range items {
speed, err := strconv.Atoi(mustGetSpeed())
// ...
_, _, _ = item, speed, err
}
}
}
func BenchmarkClosure2(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, item := range items {
mustGetSpeed := func() string {
speed := sound
// ...
return speed
}
speed, err := strconv.Atoi(mustGetSpeed())
// ...
_, _, _ = item, speed, err
}
}
}
func BenchmarkClosure3(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, item := range items {
speed, err := strconv.Atoi(func() string {
speed := sound
// ...
return speed
}())
// ...
_, _, _ = item, speed, err
}
}
}
Output:
BenchmarkClosure1 10000 156031 ns/op
BenchmarkClosure2 10000 156955 ns/op
BenchmarkClosure3 10000 152546 ns/op