首页 > 解决方案 > 编译的二进制文件比运行“go run”慢

问题描述

我正在尝试解决代码难题的出现(所以对于那些尚未完成第一天的人来说,剧透警报),我遇到了一些我无法理解的事情。

我有一个函数,它根据其他一些数字列表生成一个数字列表,它返回第二次遇到的第一个数字:

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
        }
    }
}

当我使用 运行我的代码时go run,该函数需要大约 15 毫秒才能完成。但是当我构建一个可执行文件go build并运行它时,大约需要 40 毫秒才能完成。我真的很想知道为什么这些运行之间的执行时间会有如此大的差异。他们不应该是一样的吗?或者像 GC 这样的东西会减慢go build可执行文件的速度?

标签: go

解决方案


堆栈溢出

寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。


您的基准无效。它不完整。它是不可重现的。


在 Go 中,使用testing包对代码进行基准测试。例如,

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)
    }
}

输出:

$ go test t94_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkFirstFrequency-4        1000000    7206 ns/op    3342 B/op    16 allocs/op
$ 

警告:您可能有一个无限循环:

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)
    }
}

输出:

$ go test t94_test.go -bench=.
goos: linux
goarch: amd64
BenchmarkFirstFrequency-4       fatal error: runtime: out of memory

推荐阅读