Некоторые базовые точки:
- Вызовы методов Python «дороги» из-за их интерпретируемой природы . Теоретически, если ваш код достаточно прост, разбивка кода Python оказывает негативное влияние, помимо читабельности и повторного использования ( что является большим преимуществом для разработчиков, а не для пользователей ).
- Принцип единой ответственности (SRP) делает код читаемым, его проще тестировать и обслуживать.
- У проекта есть особый вид фона, где мы хотим, чтобы читаемый код, тесты и производительность по времени.
Например, подобный код, который вызывает несколько методов (x4), медленнее, чем следующий, который является одним.
from operator import add
class Vector:
def __init__(self,list_of_3):
self.coordinates = list_of_3
def move(self,movement):
self.coordinates = list( map(add, self.coordinates, movement))
return self.coordinates
def revert(self):
self.coordinates = self.coordinates[::-1]
return self.coordinates
def get_coordinates(self):
return self.coordinates
## Operation with one vector
vec3 = Vector([1,2,3])
vec3.move([1,1,1])
vec3.revert()
vec3.get_coordinates()
По сравнению с этим:
from operator import add
def move_and_revert_and_return(vector,movement):
return list( map(add, vector, movement) )[::-1]
move_and_revert_and_return([1,2,3],[1,1,1])
Если я собираюсь распараллелить что-то подобное, это довольно объективная потеря производительности. Ум это просто пример; В моем проекте есть несколько мини-подпрограмм с такой математикой, хотя с ними гораздо проще работать, нашим профилировщикам это не нравится.
Как и где мы можем использовать SRP без ущерба для производительности в Python, поскольку его внутренняя реализация напрямую влияет на него?
Существуют ли обходные пути, например, какой-то препроцессор, который готовит релиз?
Или Python плохо справляется с обработкой кода?
Ответы:
К сожалению, да, Python работает медленно, и есть много анекдотов о людях, которые резко увеличивают производительность, вставляя функции и делая их код безобразным.
Существует обходной путь, Cython, который является скомпилированной версией Python и намного быстрее.
- Редактировать Я просто хотел обратиться к некоторым комментариям и другим ответам. Хотя суть их, возможно, не специфична для Python. но более общая оптимизация.
Не оптимизируйте, пока у вас есть проблемы, а затем ищите узкие места
Вообще хороший совет. Но предполагается, что «нормальный» код обычно является быстродействующим. Это не всегда так. Отдельные языки и структуры имеют свои особенности. В этом случае вызовы функции.
Это всего лишь несколько миллисекунд, другие вещи будут медленнее
Если вы выполняете свой код на мощном настольном компьютере, вам, вероятно, все равно, если ваш однопользовательский код выполняется за несколько секунд.
Но бизнес-код, как правило, выполняется для нескольких пользователей и требует более одной машины для поддержки нагрузки. Если ваш код выполняется в два раза быстрее, это означает, что вы можете иметь вдвое больше пользователей или вдвое меньше машин.
Если вы владеете своими машинами и центром обработки данных, то, как правило, у вас большой объем ресурсов процессора. Если ваш код работает немного медленно, вы можете его освоить, по крайней мере, до тех пор, пока вам не понадобится купить второй компьютер.
В наши дни облачных вычислений, когда вы используете только ту вычислительную мощность, которая вам требуется, и не более, существует прямая цена за неэффективный код.
Повышение производительности может значительно сократить основные расходы на облачный бизнес, и производительность действительно должна быть на первом месте.
источник
Многие потенциальные проблемы с производительностью не являются проблемой на практике. Проблема, которую вы поднимаете, может быть одной из них. В просторечии мы называем беспокойство об этих проблемах без доказательства того, что они являются актуальными проблемами преждевременной оптимизации.
Если вы пишете интерфейс для веб-службы, вызовы функций не окажут существенного влияния на вашу производительность, поскольку стоимость отправки данных по сети намного превышает время, необходимое для вызова метода.
Если вы пишете жесткий цикл, который обновляет видеоэкран шестьдесят раз в секунду, то это может иметь значение. Но в тот момент я утверждаю, что у вас есть большие проблемы, если вы пытаетесь использовать Python для этого, работа, для которой Python, вероятно, не очень подходит.
Как всегда, вы узнаете, как измерить. Запустите профилировщик производительности или несколько таймеров над вашим кодом. Посмотрите, действительно ли это проблема на практике.
Принцип единой ответственности не является законом или мандатом; это руководство или принцип. Дизайн программного обеспечения всегда о компромиссах; нет абсолютов. Нередко можно поменять удобочитаемость и / или удобство обслуживания на скорость, поэтому вам, возможно, придется пожертвовать SRP на алтаре производительности. Но не делайте этого компромисса, если не знаете, что у вас проблемы с производительностью.
источник
Сначала некоторые уточнения: Python - это язык. Существует несколько различных интерпретаторов, которые могут выполнять код, написанный на языке Python. Ссылочная реализация (CPython) обычно является той, на которую ссылаются, когда кто-то говорит о «Python», как будто это реализация, но важно быть точным, говоря о характеристиках производительности, поскольку они могут сильно отличаться в разных реализациях.
Случай 1.) Если у вас есть чистый код Python (<= Python Language version 3.5, 3.6 имеет «поддержку бета-уровня»), который опирается только на чистые модули Python, вы можете использовать SRP везде и использовать PyPy для его запуска. PyPy ( https://morepypy.blogspot.com/2019/03/pypy-v71-released-now-uses-utf-8.html ) является интерпретатором Python, который имеет компилятор Just in Time (JIT) и может удалить функцию накладные расходы при условии, что у них достаточно времени для «прогрева» путем отслеживания исполняемого кода (несколько секунд IIRC). **
Если вы ограничены использованием интерпретатора CPython, вы можете извлечь медленные функции в расширения, написанные на C, которые будут предварительно скомпилированы и не будут подвержены каким-либо затратам интерпретатора. Вы по-прежнему можете использовать SRP везде, но ваш код будет разделен между Python и C. Это лучше или хуже для удобства сопровождения, чем выборочное отказ от SRP, но придерживаться только кода Python зависит от вашей команды, но если у вас есть критические для производительности разделы вашего код, это, несомненно, будет быстрее, чем даже самый оптимизированный чистый Python-код, интерпретируемый CPython. Многие из самых быстрых математических библиотек Python используют этот метод (numpy и scipy IIRC). Который - хороший переход в Случай 2 ...
Случай 2.) Если у вас есть код Python, который использует расширения C (или полагается на библиотеки, которые используют расширения C), PyPy может или не может быть полезным в зависимости от того, как они написаны. См. Http://doc.pypy.org/en/latest/extending.html для получения подробной информации, но в целом сводится к тому, что CFFI имеет минимальные издержки, тогда как CTypes медленнее (использование его с PyPy может быть даже медленнее, чем CPython)
Cython ( https://cython.org/ ) - еще один вариант, с которым у меня не так много опыта. Я упоминаю это для полноты картины, чтобы мой ответ мог «стоять сам по себе», но не требует какой-либо экспертизы. Из-за моего ограниченного использования я чувствовал, что мне пришлось работать усерднее, чтобы получить те же улучшения скорости, которые я мог получить «бесплатно» с PyPy, и если мне нужно что-то лучше, чем PyPy, было бы так же легко написать свое собственное расширение C ( что имеет преимущество, если я повторно использую код в другом месте или извлекаю его часть в библиотеку, весь мой код все еще может работать под любым интерпретатором Python и не должен запускаться Cython).
Я боюсь быть "заблокированным" в Cython, тогда как любой код, написанный для PyPy, также может работать под CPython.
** Некоторые дополнительные заметки о PyPy в производстве
Будьте очень осторожны при принятии любых решений, которые имеют практический эффект «привязки» к PyPy в большой кодовой базе. Поскольку некоторые (очень популярные и полезные) сторонние библиотеки не работают хорошо по причинам, упомянутым ранее, это может привести к очень трудным решениям позже, если вы поймете, что вам нужна одна из этих библиотек. Мой опыт в основном заключается в использовании PyPy для ускорения некоторых (но не всех) микросервисов, которые чувствительны к производительности в корпоративной среде, где это добавляет незначительную сложность в нашу производственную среду (у нас уже развернуто несколько языков, некоторые с разными основными версиями, такими как 2.7 против 3,5 работает в любом случае).
Я обнаружил, что использование PyPy и CPython регулярно заставляло меня писать код, который полагается только на гарантии, предоставляемые самой спецификацией языка, а не на детали реализации, которые могут быть изменены в любое время. Вы можете подумать о таких деталях как дополнительное бремя, но я нашел это ценным в своем профессиональном развитии, и я думаю, что это «полезно» для экосистемы Python в целом.
источник