Документация Engee

BenchmarkTools

Страница в процессе перевода.

BenchmarkTools упрощает отслеживание производительности кода Julia, предоставляя фреймворк для написания и запуска групп тестов производительности, а также для сравнения их результатов.

Этот пакет используется для написания и запуска тестов производительности, содержащихся в BaseBenchmarks.jl.

Инфраструктура непрерывной интеграции для автоматизированного тестирования производительности языка Julia не входит в этот пакет. Ее можно найти в Nanosoldier.jl.

Быстрое начало работы

Основной макрос, предоставляемый BenchmarkTools, — это @benchmark:

julia> using BenchmarkTools

# Выражение `setup` выполняется один раз для каждой пробы и не включается
# в результаты замера времени. Обратите внимание, что для каждой пробы может потребоваться несколько вычислений
# ядра теста производительности. Подробнее см. в руководстве по BenchmarkTools.
julia> @benchmark sort(data) setup=(data=rand(10))
BenchmarkTools.Trial:
 10000 samples with 968 evaulations took a median time of 90.902 ns (0.00% GC)
 Time  (mean ± σ):   94.936 ns ±  47.797 ns  (GC: 2.78% ±  5.03%)
 Range (min … max):  77.655 ns … 954.823 ns  (GC: 0.00% … 87.94%)

          ▁▃▅▆▇█▇▆▅▂▁
  ▂▂▃▃▄▅▆▇███████████▇▆▄▄▃▃▂▂▂▂▂▂▂▂▂▂▂▁▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂
  77.7 ns         Histogram: frequency by time           137 ns

 Memory estimate: 160 bytes, allocs estimate: 1.

Для быстрой проверки работоспособности можно использовать макрос @btime, представляющий собой удобную оболочку вокруг @benchmark, вывод которой аналогичен выводу встроенного макроса Julia @time:

julia> @btime sin(x) setup=(x=rand())
  4.361 ns (0 allocations: 0 bytes)
0.49587200950472454

Если вы хотите профилировать быстро выполняющуюся команду, можно использовать @bprofile sin(x) setup=(x=rand()), а затем ваши любимые инструменты для отображения результатов (Profile.print или графическое средство просмотра).

Если тестируемое выражение зависит от внешних переменных, следует использовать $ для их «интерполяции» в выражение теста производительности, чтобы избежать проблем, связанных с тестированием с использованием глобальных переменных. По сути, любая интерполированная переменная $x или выражение $(...) «предварительно вычисляются» до начала тестирования производительности:

julia> A = rand(3,3);

julia> @btime inv($A);            # интерполируем глобальную переменную A с помощью $A
  1.191 μs (10 allocations: 2.31 KiB)

julia> @btime inv($(rand(3,3)));  # интерполяция: вызов rand(3,3) происходит перед тестированием производительности
  1.192 μs (10 allocations: 2.31 KiB)

julia> @btime inv(rand(3,3));     # вызов rand(3,3) включается во время тестирования производительности
  1.295 μs (11 allocations: 2.47 KiB)

Иногда при интерполяции переменных в очень простые выражения компилятор может получать больше информации, чем предполагалось, из-за чего вычисления «выносятся» за пределы кода теста производительности.

julia> a = 1; b = 2
2

julia> @btime $a + $b
  0.024 ns (0 allocations: 0 bytes)
3

Как правило, если вы видите, что выполнение теста производительности заняло менее наносекунды, скорее всего, произошел такой обход выполнения. Предотвратить это можно путем именования и разыменовывая интерполированных переменных.

julia> @btime $(Ref(a))[] + $(Ref(b))[]
  1.277 ns (0 allocations: 0 bytes)
3

Как описано в руководстве, пакет BenchmarkTools поддерживает множество других функций, как для получения дополнительных выходных данных, так и для более точного управления процессом тестирования производительности.