douyun7718 2018-12-02 13:08
浏览 315
已采纳

编译二进制文件比运行“ go run”要慢

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?

  • 写回答

1条回答 默认 最新

  • dongtuji0992 2018-12-02 13:37
    关注

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 线程问题判断多次进入
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败