Почему `time.Since(start).Seconds()` всегда возвращает 0?

Я работаю над первой главой Язык программирования Go (серия Addison-Wesley Professional Computing), а в третьем упражнении книги меня просят измерить производительность кода с помощью time.

Итак, я придумал следующий код.

start := time.Now()
var s, sep string
for i := 1; i < len(os.Args); i++ {
    s += sep + os.Args[i]
    sep = " "
}
fmt.Print(s)
fmt.Printf("\nTook %.2fs \n", time.Since(start).Seconds())
fmt.Println("------------------------------------------------")
start2 := time.Now()
fmt.Print(strings.Join(os.Args[1:], " "))
fmt.Printf("\nTook %.2fs", time.Since(start2).Seconds())

Когда я запускал этот код на Windows и Mac, он всегда возвращал 0,00 секунды. Я добавил паузу в свой код, чтобы проверить, правильно ли это, и все ли в порядке. Чего я не понимаю, так это почему он всегда возвращает 0.0.0.

Почему мой вопрос получает отрицательные голоса? Пожалуйста, прокомментируйте, чтобы я знал, что можно улучшить

Cee 24.04.2019 07:16
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
0
1
369
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Между временем начала и вызовами time.Since() очень мало кода, в первом примере всего несколько конкатенаций строк и вызов fmt.Print(), во втором примере — только один вызов fmt.Print(). Они выполняются вашим компьютером очень быстро.

Так быстро, что результат, скорее всего, меньше миллисекунды. И вы печатаете прошедшее время, используя глагол %.2f, который округляет секунды до двух дробных цифр. Это означает, что если прошедшее время меньше 0.005 sec, оно будет округлено до 0. Вот почему вы видите 0.00s напечатанным.

Если вы измените формат на %0.12f, вы увидите что-то вроде:

Took 0.000027348000s 
Took 0.000003772000s

Также обратите внимание, что значение time.Duration, возвращаемое time.Since(), реализует fmt.Stringer и разумно "форматирует" себя в единицу, которая является более значимой. Так что можете печатать как есть.

Например, если вы напечатаете это так:

fmt.Println("Took", time.Since(start))
fmt.Println("Took", time.Since(start2))

Вы увидите что-то вроде этого:

Took 18.608µs
Took 2.873µs

Также обратите внимание, что если вы хотите измерить производительность некоторого кода, вам следует использовать встроенные средства тестирования и тестирования Go, а именно пакет testing. Подробнее см. Порядок кода и производительность.

Другие вопросы по теме