Скомпилированный бинарный файл работает медленнее, чем "go run" - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь решить появление головоломок с кодом (так что спойлер предупреждает тех из вас, кто еще не закончил первый день), и я столкнулся с чем-то, что не могу обернуть голову.

У меня есть функция, которая генерирует список чисел на основе некоторого другого списка чисел, и возвращает первое число, которое встречается во второй раз:

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 исполняемым файлом?

1 Ответ

0 голосов
/ 02 декабря 2018

Переполнение стека

Вопросы, требующие помощи по отладке («почему этот код не работает?»), Должны включать в себя желаемое поведение, конкретную проблему или ошибку и самое короткоекод, необходимый для его воспроизведения в самом вопросе.


Ваш эталонный тест недействителен.Это неполноЭто не воспроизводится.


В 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...