Рубрики
Без рубрики

Как проводить тест Python код: TimeIt, cprofile и Более

Многие из статей в этой серии пользуются функцией Python, которая позволяет нам выполнять … Теги с производительностью, Python, тестированием.

Как python (14 часть серии)

Многие из статей в этой серии пользуются функцией Python, которая позволяет нам проверять наш код, и я наконец-то хотел, чтобы объяснить, как это работает и как его использовать.

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

Проблема введения

Чтобы начать говорить о том, как проводить тест на код Python, нам нужно определить его. На высоком уровне тест производительности – это все, что проверяет скорость, надежность, масштабируемость и/или устойчивость программного обеспечения. Для наших целей мы будем смотреть на скорость. В частности, мы смотрим на разные способы сравнить скорость двух программ, использующих их относительные времена выполнения.

Когда дело доходит до программного обеспечения для тестирования производительности, процесс не всегда легко или очевиден. В частности, есть много подводных камней. Например, тесты производительности могут влиять всевозможные факторы, такие как фоновые процессы (то есть Spotify, Eclipse, Deskub Desktop и т. Д.).

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

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

Во всяком случае, целью настоящей статьи – смотреть на несколько разных способов, которыми мы можем провести тестовый код в Python. Давайте копать!

Растворы

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

Производительность тестирования грубой силой

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

Чтобы сделать это в Python, мы можем воспользоваться преимуществами datetime библиотека:

import datetime
start_time = datetime.datetime.now()
# insert code snippet here
end_time = datetime.datetime.now()
print(end_time - start_time)

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

Тестирование производительности с использованием библиотеки времени

Если вы бы предпочли иметь все этот мусор в мусор с добавлением нескольких льгот, проверьте Время течения библиотека. С Время течения Библиотека, в основном есть два основных способа тестирования кода: командная строка или встроенные. Для наших целей мы посмотрим на встроенную версию, поскольку это то, что я использую для всех моих тестов.

Чтобы проверить код, используя Время течения Библиотека, вам нужно позвонить либо Время течения функция или повторить функция. Либо один в порядке, но повторить Функция дает немного больше контроля.

В качестве примера мы проверим следующий фрагмент кода от Более ранняя статья о похвате списка :

[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]

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

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Если сделано правильно, это запустит фрагмент в миллион раз и возвращает среднее время выполнения в результате. Конечно, вы можете изменить количество итераций, используя Номер Аргумент ключевых слов:

import timeit
timeit.timeit("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]", number=1000)

Естественно, мы можем сделать этот тест еще дальше, запустив его несколько раз, используя функцию повтора:

import timeit
timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

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

import timeit
min(timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]"))

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

Тестирование производительности с использованием библиотеки CPROFIL

За пределами Время течения И прямая грубая сила, вы всегда можете использовать другие инструменты профилирования, такие как CPROFILE Отказ Как Время течения мы можем использовать плечо CPROFILE Получить статистику времени выполнения из раздела кода. Конечно, Cprofile довольно подробнее. Например, мы можем запускать одно и то же понимание списка сверху следующим образом:

import cProfile
cProfile.run("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

В результате вы получаете хороший отчет, который выглядит так:

4 function calls in 0.000 seconds 

    Ordered by: standard name 

    ncalls tottime percall cumtime percall filename:lineno(function) 
        1 0.000 0.000 0.000 0.000 :1() 
        1 0.000 0.000 0.000 0.000 :1() 
        1 0.000 0.000 0.000 0.000 {built-in method builtins.exec} 
        1 0.000 0.000 0.000 0.000 {method 'disable' of '\_lsprof.Profiler' objects}

Здесь мы получаем хороший стол, который включает в себя много полезной информации. В частности, каждая строка указывает, что выполнена функция, которая была выполнена, и каждый столбец разбивает другой сегмент времени выполнения. Например, Функция называлась один раз ( NCalls ) и занял 0,000 секунды ( TOTTIME ) ИСКЛЮЧИТЕЛЬНЫЕ ПРИЗЫТЫЕ ПРИМЕНЕНИЯ. Чтобы понять все остальное в этой таблице, проверьте следующую поломку всех шести столбцов:

  • NCalls : количество раз этой конкретной функции называли

    • Это число может быть фактически записано как фракция (например, 3/1 ), где первое значение – количество общих вызовов, а второе значение – количество примитивных вызовов (не рекурсивных).
  • TOTTIME : Общее количество времени, которое функция, потраченная на выполнение не в том числе призывы к подфункциям
  • Percall (Во-первых): соотношение Tottime до NCalls (то есть среднее количество времени, проведенное в этой функции, исключая подфункции)
  • CumTime : Общее количество времени, которое функция, потраченная выполнением, включая вызовы в подфункции
  • Percall (Во-вторых): отношение CumTime до примитивных вызовов (то есть. Среднее количество времени, проведенного в этой функции)
  • Имя имена: Lineno (Функция) : Имя файла, номер линии и функция

Как видите, CPROFILE Помогает вам заглянуть на внутреннюю работу кодового фрагмента. Конечно, вы не получаете отличные зернистые сроки, так что это работает лучше, как комплимент Время течения а не замена. Это сказал, я думаю CPROFILE было бы отлично для профилирования больших сценариев. Таким образом, вы можете определить, какие функции нуждаются в оптимизации.

Тестирование производительности с внешними библиотеками

В то время как Python предоставляет много способов прозовражать свой собственный код, есть и другие библиотеки, которые мы можем использовать также. Например:

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

Испытание

На данный момент я обычно разделяю некоторые показатели производительности для каждого из решений выше, но это не имеет смысла в этом контексте. Вместо этого пришло время прыгать прямо к испытанию!

Выберите одну из статей в этой серии и запустите свои собственные метрики производительности на каждом из решений. Так как я обычно бегаю время Может быть, вы можете попробовать использовать один из других инструментов из этой статьи. Например, попробуйте запустить cprofile на все Решения для форматирования строки Отказ

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

Немного повтора

Как всегда, мне нравится закончить вещи со списком вариантов. Имейте в виду, что каждый раствор использует пример фрагмента кода. В этом случае я выбрал понимание списка, но вы можете использовать любой фрагмент:

# Brute force solution
import datetime
start_time = datetime.datetime.now()
[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)] # example snippet
end_time = datetime.datetime.now()
print(end_time - start_time)

# timeit solution
import timeit
min(timeit.repeat("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]"))

# cProfile solution
import cProfile
cProfile.run("[(a, b) for a in (1, 3, 5) for b in (2, 4, 6)]")

Ну, это все, что у меня есть! Если у вас есть какие-либо инструменты производительности, чтобы добавить в список, не стесняйтесь делиться ими в комментариях.

Тем временем у меня есть много того, как стать статьи Python вас, можно заинтересовать:

Если вы предпочитаете Visual Media, У меня есть канал YouTube Что в настоящее время сосредоточено на объяснении содержания из этой серии. Голова там и брось мне подписку, чтобы помочь мне настроить мой канал.

Наконец, вы всегда можете получить последний контент Renegade Coder, отправленный в свой почтовый ящик через Список электронной почты Отказ Если вы хотите пойти на лишнюю милю, Брось меня пару баксов на Пальтаоне Отказ Вы не пожалеете об этом!

Во всяком случае, до следующего раза!

Пост Как проводить тест Python Code: TimeIt, Cprofile и многое другое появился первым на Renegade Coder Отказ

Как python (14 часть серии)

Оригинал: “https://dev.to/renegadecoder94/how-to-performance-test-python-code-timeit-cprofile-and-more-2pgi”