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