Как правильно запустить StartTime и StopTime в тесте Голанг? - PullRequest
0 голосов
/ 25 августа 2018

Я написал тест для проверки скорости двух генераторов чисел Фибоначчи, и здесь на github .

имеется исходный код .
func BenchmarkFib(b *testing.B) {
    fibFuncs := []struct {
        name string
        f    func(int) int
    }{
        {"recursive", fibRecu},
        {"iterative", fibIter},
    }
    for _, fibFunc := range fibFuncs {
        // calculate k'th Fibonacci number
        for k := 10; k < 1001; k *= 10 {
            b.Run(fmt.Sprintf("%s Fib %v", fibFunc.name, k), func(b *testing.B) {
                for n := 0; n < b.N; n++ {
                    //                  b.StopTimer()
                    // reset the memo
                    memo = map[int]int{0: 0, 1: 1, 2: 1}
                    //                  b.StartTimer()
                    fibFunc.f(k)
                }
            })
        }
    }
}

Как есть, эталонный тест работает, и вывод

nos (master) fibonacci $ go test -bench .
goos: linux
goarch: amd64
pkg: github.com/nosarthur/dynamicP/fibonacci
BenchmarkFib/recursive_Fib_10-4                  1000000              1256 ns/op
BenchmarkFib/recursive_Fib_100-4                  100000             18256 ns/op
BenchmarkFib/recursive_Fib_1000-4                  10000            206109 ns/op
BenchmarkFib/iterative_Fib_10-4                 10000000               218 ns/op
BenchmarkFib/iterative_Fib_100-4                 5000000               292 ns/op
BenchmarkFib/iterative_Fib_1000-4                2000000               881 ns/op
PASS
ok      github.com/nosarthur/dynamicP/fibonacci 12.208s

Однако я добавил b.StopTime() и b.StartTime(), чтобы исключить время для сброса заметки. С этими двумя строками без комментариев, тест зависает, а частичный вывод равен

nos (master *) fibonacci $ go test -bench .
goos: linux
goarch: amd64
pkg: github.com/nosarthur/dynamicP/fibonacci
BenchmarkFib/recursive_Fib_10-4                  1000000              2139 ns/op
BenchmarkFib/recursive_Fib_100-4                  100000             24775 ns/op
BenchmarkFib/recursive_Fib_1000-4                   5000            239197 ns/op
BenchmarkFib/iterative_Fib_10-4                 ^Csignal: interrupt
FAIL    github.com/nosarthur/dynamicP/fibonacci 269.067s

Как правильно исключить сброс заметок? Моя версия go 1.10.1

1 Ответ

0 голосов
/ 25 августа 2018

Что происходит, так это то, что ваши функции действительно быстрые, особенно в случае итеративной функции, и сброс вашей карты (а также сами функции StartTimer и StopTimer со статистикой времени выполнения распределение) намного, намного медленнее.

Итак, что происходит, когда вы вызываете StopTimer, он устанавливает внутреннюю отслеживаемую продолжительность теста только на время, необходимое для запуска функции. Хорошо, угадайте, как он оценивает, сколько итераций нужно выполнить в течение установленного контрольного времени? Да, вы уже догадались - внутренняя продолжительность.

Таким образом, для выполнения вашей итеративной функции требуется около 10 нс, для сброса карты требуется около 250 нс, а для функций таймера требуется значительно больше времени, но, согласно оценкам, каждый прогон занимает всего 20 нс и соответственно устанавливает количество итераций.

Мое предложение - в этом случае не используйте функции StartTimer/StopTimer, а просто добавьте в свои тесты третий прогон, который не работает - в основном:

{"baseline", func(int) int {return 0}},

Затем просто вычтите времена из этой функции из двух других наборов, чтобы оценить, сколько ns / op было в распределении по сравнению с самими функциями.

Вот результаты, когда я запустил это:

BenchmarkFib/baseline_Fib_10-2           5000000           357 ns/op
BenchmarkFib/baseline_Fib_100-2          5000000           327 ns/op
BenchmarkFib/baseline_Fib_1000-2         5000000           310 ns/op
BenchmarkFib/recursive_Fib_10-2          1000000          1659 ns/op
BenchmarkFib/recursive_Fib_100-2           50000         24898 ns/op
BenchmarkFib/recursive_Fib_1000-2           5000        301771 ns/op
BenchmarkFib/iterative_Fib_10-2          5000000           333 ns/op
BenchmarkFib/iterative_Fib_100-2         3000000           394 ns/op
BenchmarkFib/iterative_Fib_1000-2        1000000          1052 ns/op
PASS
ok      _/tmp/dynamicP/fibonacci    15.305s
...