Введение
Производительность программы играет важную роль в разработке ПО. В Python существует несколько способов измерения скорости выполнения кода, начиная от встроенных инструментов до специализированных библиотек. Рассмотрим четыре метода оценки производительности Python-программ.
Использование модуля time
Один из самых простых способов измерения времени выполнения кода — использование встроенного модуля time.
import time
def slow_function():
time.sleep(2)
start_time = time.time()
slow_function()
end_time = time.time()
execution_time = end_time - start_time
print(f"Время выполнения: {execution_time:.6f} секунд")
# Пример вывода: Время выполнения: 2.007304 секунд
Внутри функции slow_function() специально добавлена задержка на 2 секунды для демонстрации данного подхода. Принцип работы довольно прост: сначала в переменную start_time сохраняется время начала выполнения функции slow_function(), затем функция вызывается, а в end_time сохраняется время её завершения. После этого вычисляется разница между end_time и start_time, что позволяет определить продолжительность выполнения.
Данный метод подходит для грубой оценки скорости выполнения небольших фрагментов кода.
Использование модуля timeit
Для более точных измерений в Python присутствует стандартный модуль timeit. Он учитывает особенности работы интерпретатора Python, такие как JIT-компиляция и кэширование.
import timeit
code_to_test = """
result = [x**2 for x in range(1000)]
"""
execution_time = timeit.timeit(code_to_test, number=10000)
print(f"Среднее время выполнения: {execution_time / 10000:.8f} секунд")
# Пример вывода: Среднее время выполнения: 0.00017912 секунд
В переменной code_to_test хранится строка с кодом, который создаёт список квадратов чисел от 0 до 999 с помощью генератора списков. Затем функция timeit() выполняет этот код 10 000 раз (количество выполнений указано в параметре number) и измеряет общее время выполнения. Полученное время мы делим на количество запусков для вычисления среднего времени выполнения одного прохода, после чего выводится итоговый результат.
Использование timeit удобно, когда нужно провести серию замеров и получить усреднённое значение.
Использование cProfile
Для анализа скорости выполнения всей программы на Python и определения узких мест — можно воспользоваться модулем cProfile.
import cProfile
def test_function():
total = sum([x**2 for x in range(10000)])
return total
cProfile.run('test_function()')
# Пример вывода:
# 6 function calls in 0.002 seconds
#
# Ordered by: standard name
#
# ncalls tottime percall cumtime percall filename:lineno(function)
# 1 0.000 0.000 0.002 0.002 :1( )
# 1 0.000 0.000 0.002 0.002 main.py:3(test_function)
# 1 0.002 0.002 0.002 0.002 main.py:4( )
# 1 0.000 0.000 0.002 0.002 {built-in method builtins.exec}
# 1 0.000 0.000 0.000 0.000 {built-in method builtins.sum}
# 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
В коде первым делом была определена функция test_function(), которая вычисляет сумму квадратов чисел от 0 до 9 999 с помощью генератора списков. Результат сохраняется в переменную total и возвращается. Далее идёт вызов функции cProfile.run() с передачей в неё test_function(), что позволяет запустить функцию test_function() и измерить её производительность.
Использование line_profiler
Для детального анализа времени выполнения отдельных строк кода удобно использовать сторонний модуль line_profiler.
Установка модуля:
pip install line-profiler
Пример кода:
from line_profiler import LineProfiler
def test_function():
total = sum([x**2 for x in range(10000)])
return total
profiler = LineProfiler()
profiler.add_function(test_function)
profiler.enable()
test_function()
profiler.disable()
profiler.print_stats()
# Пример вывода:
# Testing started at 1:12 ...
# Launching pytest with arguments C:\Lesson\main.py --no-header --no-summary -q in C:\Lesson
#
# ============================= test session starts =============================
# collecting ... collected 1 item
#
# main.py::test_function PASSED [100%]
#
# ======================== 1 passed, 1 warning in 0.09s =========================
#
# Process finished with exit code 0
Первым делом в коде снова у нас определена функция test_function(), которая вычисляет сумму квадратов чисел от 0 до 9 999 с использованием генератора. Результат сохраняется в переменной total и возвращается.
Далее создаётся объект profiler класса LineProfiler(), который будет отслеживать выполнение функций. С помощью profiler.add_function(test_function) мы указываем, что хотим анализировать test_function(). Затем включаем профилирование (profiler.enable()) вызываем test_function() после чего отключаем профилирование (profile.disabled()).
В конце вызываем profiler.print_status(), для вывода детализированной статистики, которая покажет:
- время выполнения каждой строки кода,
- количество вызовов,
- процентное соотношение времени выполнения каждой строки от общего времени работы функции.
Заключение
В ходе статьи мы с Вами рассмотрели четыре способа для измерения скорости работы Python-кода. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂
Мой Telegram канал
Мой YouTube канал
Курс по созданию телеграм-ботов на Python с фреймворком Aiogram