В самый первый раз, когда вы import goo
из любого места (внутри или вне функции), загружается goo.py
(или другая импортируемая форма), и sys.modules['goo']
устанавливается в созданный таким образом объект модуля. Любой будущий импорт в рамках того же запуска программы (опять же, внутри или вне функции) просто найдите sys.modules['goo']
и привяжите его к barename goo
в соответствующей области. Поиск dict и привязка имени - очень быстрые операции.
Предполагая, что самый первый import
в любом случае полностью амортизируется за время выполнения программы, наличие «соответствующей области» на уровне модуля означает, что каждое использование goo.this
, goo.that
и т. Д. Представляет собой два поиска dict - один для goo
и один для имени атрибута. Если он находится на «функциональном уровне», то при каждом запуске функции оплачивается одна дополнительная установка локальной переменной (даже быстрее, чем при поиске по словарю!), Но сохраняется один поиск по словарю (замена его на поиск по локальной переменной, невероятно быстро) для каждого goo.this
(и т. д.), что в основном сокращает время поиска вдвое.
Так или иначе, мы говорим о нескольких наносекундах, так что вряд ли это стоящая оптимизация. Одно потенциально существенное преимущество наличия import
внутри функции состоит в том, что эта функция может вообще не понадобиться при данном запуске программы, например, эта функция имеет дело с ошибками, аномалиями и редкими ситуациями в целом; в этом случае любой прогон, которому не нужны функциональные возможности, даже не будет выполнять импорт (и это экономия микросекунд, а не только наносекунд), только запуски, которые действительно нуждаются в функциональности, будут платить (скромную, но измеримую) цену.
Это по-прежнему оптимизация, которая имеет смысл только в довольно экстремальных ситуациях, и есть много других, которые я бы рассмотрел, прежде чем пытаться таким образом выжать микросекунды.
person
Alex Martelli
schedule
22.06.2010
import
очень дорог, даже если модуль уже загружен). Если вы хотите повысить скорость, быстрее (если вы обращаетесь к модулю как минимум 4-5 раз) просто назначьте модуль локальной переменной в качестве первого действия, которое вы делаете в своей функции, а затем обращайтесь к нему через эту локальную переменную. (потому что поиск локальных переменных ОЧЕНЬ быстрый). - person Nick Bastin   schedule 22.06.2010import
модуль на уровне файла, как обычно, а затем внутри функция назначает модуль локальной переменной. Чтобы назначение было целесообразным, вам нужно будет получить доступ к модулю, вероятно, как минимум 4 раза внутри функции - если вы используете модуль реже, чем это, выполнение прямого поиска module.symbol на глобальном уровне не будет медленнее чем локальное присвоение / поиск. - person Nick Bastin   schedule 23.06.2010neither
из этих вещей в качестве общей практики - вы должны импортировать на уровне модуля и использовать методы / функции в пространстве имен, в котором они в настоящее время находятся, и только в ситуациях с экстремальной производительностью следует думать о микрооптимизациях, таких как переназначение на местного. - person Nick Bastin   schedule 24.06.2010