Как проверить функцию init () - PullRequest
0 голосов
/ 31 октября 2018

Я играл со следующим кодом Go, который вычисляет количество населения по справочной таблице:

package population

import (
        "fmt"
)

var pc [256]byte

func init(){
        for i := range pc {
                pc[i] = pc[i/2] + byte(i&1)
        }
}

func countPopulation() {
        var x uint64 = 65535
        populationCount := int(pc[byte(x>>(0*8))] +
                pc[byte(x>>(1*8))] +
                pc[byte(x>>(2*8))] +
                pc[byte(x>>(3*8))] +
                pc[byte(x>>(4*8))] +
                pc[byte(x>>(5*8))] +
                pc[byte(x>>(6*8))] +
                pc[byte(x>>(7*8))])

        fmt.Printf("Population count: %d\n", populationCount)
}

Я написал следующий код для проверки производительности вышеуказанного блока кода:

package population

import "testing"

func BenchmarkCountPopulation(b *testing.B) {
        for i := 0; i < b.N; i++ {
                countPopulation()
        }
}

Который дал мне следующий результат:

100000             18760 ns/op
PASS
ok      gopl.io/ch2     2.055s

Затем я переместил код из функции init() в функцию countPopulation(), как показано ниже:

func countPopulation() {
        var pc [256]byte

        for i := range pc {
                pc[i] = pc[i/2] + byte(i&1)
        }

        var x uint64 = 65535
        populationCount := int(pc[byte(x>>(0*8))] +
                pc[byte(x>>(1*8))] +
                pc[byte(x>>(2*8))] +
                pc[byte(x>>(3*8))] +
                pc[byte(x>>(4*8))] +
                pc[byte(x>>(5*8))] +
                pc[byte(x>>(6*8))] +
                pc[byte(x>>(7*8))])

        fmt.Printf("Population count: %d\n", populationCount)
}

и снова запустил тот же код теста, который дал мне следующий результат:

100000             20565 ns/op
PASS
ok      gopl.io/ch2     2.303s

После просмотра обоих результатов становится ясно, что функция init() не входит в сферу применения эталонной функции. Вот почему выполнение первого теста заняло меньше времени по сравнению со вторым выполнением.

Теперь у меня есть еще один вопрос, на который я ищу ответ.

Если мне нужно протестировать только метод init(), учитывая, что в пакете может быть несколько функций init(). Как это сделать в golang?

Заранее спасибо.

1 Ответ

0 голосов
/ 31 октября 2018

Да, в пакете может быть несколько init(), фактически в файле может быть несколько init(). Более подробную информацию о init можно найти здесь . Помните, что init() автоматически вызывается за один раз до запуска main() вашей программы.

Тестовая среда запускает ваш код несколько раз (в вашем случае 100000). Это позволяет ему измерять очень короткие функции, а также очень длинные функции. Для теста не имеет смысла включать время для init(). Проблема в том, что вы не понимаете цель сравнительного анализа. Сравнительный анализ позволяет сравнить две или более отдельных реализаций, чтобы определить, какая из них быстрее (также вы можете сравнить производительность на основе ввода одной и той же функции). Он не говорит вам, где вы должны это делать.

То, что вы в основном делаете, известно как Преждевременная оптимизация . Именно здесь вы начинаете оптимизировать код, пытаясь сделать его максимально быстрым, не зная, где ваша программа фактически проводит большую часть своего времени. Профилирование - это процесс измерения временной и пространственной сложности программы. На практике это позволяет вам увидеть, где ваша программа проводит большую часть своего времени. Используя эту информацию, вы можете написать более эффективные функции. Более подробную информацию о профилировании в go можно найти в этом сообщении в блоге .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...