Бенчмарки NumPy#

Тестирование производительности NumPy с помощью Airspeed Velocity.

Использование#

Airspeed Velocity самостоятельно управляет сборкой и виртуальными окружениями Python, если не указано иное. Для запуска тестов производительности не требуется устанавливать разрабатываемую версию NumPy в текущее окружение Python.

Перед началом убедитесь, что скорость воздушного потока установлен. По умолчанию, asv поставляется с поддержкой anaconda и virtualenv:

pip install asv
pip install virtualenv

После добавления новых тестов производительности вы должны протестировать их локально перед отправкой pull request.

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

spin bench

Это собирает NumPy и запускает все доступные тесты производительности, определённые в benchmarks/. (Примечание: это может занять некоторое время. Каждый бенчмарк запускается несколько раз для измерения распределения времени выполнения.)

Для тестирование локальные тесты производительности, возможно, лучше запускать их без повторений:

cd benchmarks/
export REGEXP="bench.*Ufunc"
asv run --dry-run --show-stderr --python=same --quick -b $REGEXP

Где хранится регулярное выражение, используемое для сопоставления тестов производительности, в $REGEXP, и –quick используется для избежания повторений.

Для запуска тестов производительности из определённого модуля тестирования, такого как bench_core.py, просто добавьте имя файла без расширения:

spin bench -t bench_core

Для запуска теста производительности, определённого в классе, такого как MeshGrid из bench_creation.py:

spin bench -t bench_creation.MeshGrid

Сравнение изменений в результатах тестов с другой версией/коммитом/веткой, используйте --compare опция (или эквивалентная -c):

spin bench --compare v1.6.2 -t bench_core
spin bench --compare 20d03bcfd -t bench_core
spin bench -c main -t bench_core

Все вышеуказанные команды отображают результаты в виде простого текста в консоли, и результаты не сохраняются для сравнения с будущими коммитами. Для большего контроля, графического представления и сохранения результатов для будущего сравнения можно запускать команды ASV (записывать результаты и генерировать HTML):

cd benchmarks
asv run -n -e --python=same
asv publish
asv preview

Подробнее о том, как использовать asv можно найти в Документация ASV Справка по командной строке доступна как обычно через asv --help и asv run --help.

Версии для тестирования производительности#

Для тестирования или визуализации только релизов на разных машинах локально, теги с их коммитами могут быть сгенерированы, перед запуском с asv, то есть:

cd benchmarks
# Get commits for tags
# delete tag_commits.txt before re-runs
for gtag in $(git tag --list --sort taggerdate | grep "^v"); do
git log $gtag --oneline -n1 --decorate=no | awk '{print $1;}' >> tag_commits.txt
done
# Use the last 20
tail --lines=20 tag_commits.txt > 20_vers.txt
asv run HASHFILE:20_vers.txt
# Publish and view
asv publish
asv preview

Подробности о внесении этих изменений см. в репозиторий результатов бенчмарков.

Написание тестов производительности#

См. Документация ASV для основ написания бенчмарков.

Некоторые моменты для рассмотрения:

  • Набор тестов должен быть импортируемым с любой версией NumPy.

  • Параметры тестирования и т.д. не должны зависеть от того, какая версия NumPy установлена.

  • Старайтесь сохранять время выполнения теста разумным.

  • Предпочитайте time_ методы для измерения времени производительности, а не создания измерений времени через time.clock, даже если это требует некоторых манипуляций при написании теста.

  • Подготовка массивов и т.д. обычно должна помещаться в setup метод, а не time_ методов, чтобы избежать подсчета времени подготовки вместе со временем тестируемой операции.

  • Учитывайте, что большие массивы, созданные с помощью np.empty или np.zeros может не выделяться в физической памяти до обращения к памяти. Если это желаемое поведение, убедитесь, что прокомментировали его в функции настройки. Если вы тестируете алгоритм, маловероятно, что пользователь будет выполнять этот алгоритм на только что созданном пустом/нулевом массиве. Можно принудительно вызвать страничные ошибки на этапе настройки, вызвав np.ones или arr.fill(value) после создания массива.