I'm trying to solve the advent of code puzzles (so spoiler alert for those of you who haven't completed day 1), and I encountered something which I can't wrap my head around.
I have a function which generates a list of numbers based on some other list of numbers, and it returns the first number which is encountered for the second time:
func findFirstDoubleFrequency(freqs []int) int {
seen := map[int]bool{0: true}
freq := 0
for {
for _, f := range freqs {
freq += f
if seen[freq] == true {
return freq
}
seen[freq] = true
}
}
}
When I run my code with go run
, the function takes ~15ms to complete. But when I build an executable with go build
and run that, it takes ~40ms to complete. I really would like to know why there is such a difference in execution time between those runs. Shouldn't they be the same? Or is something like GC slowing things down with the go build
executable?
Stack Overflow
Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself.
Your benchmark is invalid. It's incomplete. It's not reproducible.
In Go, use the testing
package to benchmark code. For example,
package main
import (
"math/rand"
"testing"
)
func findFirstDoubleFrequency(freqs []int) int {
seen := map[int]bool{0: true}
freq := 0
for {
for _, f := range freqs {
freq += f
if seen[freq] == true {
return freq
}
seen[freq] = true
}
}
}
func BenchmarkFirstFrequency(b *testing.B) {
freqs := make([]int, 1000)
for i := range freqs {
freqs[i] = rand.Intn(len(freqs)/10)
}
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
findFirstDoubleFrequency(freqs)
}
}
Output:
$ go test t94_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkFirstFrequency-4 1000000 7206 ns/op 3342 B/op 16 allocs/op
$
WARNING: You have a possibly infinite loop:
package main
import (
"math/rand"
"testing"
)
func findFirstDoubleFrequency(freqs []int) int {
seen := map[int]bool{0: true}
freq := 0
for {
for _, f := range freqs {
freq += f
if seen[freq] == true {
return freq
}
seen[freq] = true
}
}
}
func BenchmarkFirstFrequency(b *testing.B) {
freqs := make([]int, 1000)
for i := range freqs {
freqs[i] = rand.Intn(len(freqs))
}
b.ReportAllocs()
b.ResetTimer()
for N := 0; N < b.N; N++ {
findFirstDoubleFrequency(freqs)
}
}
Output:
$ go test t94_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkFirstFrequency-4 fatal error: runtime: out of memory