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 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染