Вместо того, чтобы просто «иметь чувство», где узким местом является, почему не профиль ваш код и найти именно где?
Первой целью профилирования является проверка репрезентативной системы для определения того, что происходит медленно (или с использованием слишком большого количества ОЗУ, или из-за слишком большого объема ввода-вывода или сетевого ввода-вывода).
Профилирование обычно добавляет накладные расходы (может быть характерно замедление от 10x до 100x), и вы по-прежнему хотите, чтобы ваш код использовался как можно ближе к реальной ситуации. Извлеките тестовый кейс и изолируйте часть системы, которую необходимо протестировать. Предпочтительно, это будет написано уже в своем собственном наборе модулей.
Основные методы включают волшебство %timeit
в IPython, time.time(),
и timing decorator
(см. Пример ниже). Вы можете использовать эти методы для понимания поведения операторов и функций.
Тогда у вас есть cProfile
, который даст вам представление о проблеме на высоком уровне, чтобы вы могли обратить ваше внимание на важные функции.
Далее, посмотрите на line_profiler,
, который будет профилировать выбранные вами функции по очереди. Результат будет включать в себя подсчет количества раз, когда вызывается каждая строка, и процент времени, затраченного на каждую строку. Это именно то, что вам нужно, чтобы понять, что работает медленно и почему.
perf stat
помогает понять количество инструкций, которые в конечном итоге выполняются на процессоре, и насколько эффективно используются кеши процессора. Это позволяет осуществлять расширенную настройку матричных операций.
heapy
может отслеживать все объекты внутри памяти Python. Это отлично подходит для поиска странных утечек памяти.Если вы работаете с многолетними системами, вам будет интересен , тогда dowser
вас заинтересовал: он позволяет вам заглядывать живые объекты в длительный процесс через интерфейс веб-браузера.
Чтобы помочь вам понять, почему ваше использование ОЗУ очень велико, посмотрите memory_profiler.
Это особенно полезно для отслеживания использования ОЗУ с течением времени на маркированной диаграмме, поэтому вы можете объяснить коллегам (или вам самим), почему некоторые функции используют больше ОЗУ, чем ожидается.
Пример: Определение декоратора для автоматизации измерений
from functools import wraps
def timefn(fn):
@wraps(fn)
def measure_time(*args, **kwargs):
t1 = time.time()
result = fn(*args, **kwargs)
t2 = time.time()
print ("@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds")
return result
return measure_time
@timefn
def your_func(var1, var2):
...
Для получения дополнительной информации, я предлагаю читать High performance Python (Micha Gorelick; Ян Ozsvald) синхронизации, из которого был получен выше.
Вы понимаете эти масштабы ужасно с размером 'gn' ...? –
Да, конечно, максимальный размер l равен 9, а всегда 2 – HighwayJohn
Вы в Python 2 или 3? –