Какая разница в памяти и производительности между импортом всех функций данного модуля и только тех функций, которые нам нужны? - PullRequest
0 голосов
/ 27 декабря 2018

Например, import math импортировать все функции в математическом модуле, тогда как если мы напишем from math import sqrt,pow, то импортируются только sqrt(),pow().

Является ли их любая производительность или разница в памяти в обоих из них.

1 Ответ

0 голосов
/ 27 декабря 2018

Например, import math все функции импорта в математическом модуле, тогда как если мы пишем from math import sqrt,pow, то импортируются только sqrt(),pow().

Это немного сложнее.

Если на мгновение мы проигнорируем, что math встроен в интерпретатор (так что нет ничего, что действительно нужно загружать), независимо от того, выполняете ли вы import math, from math import sqrt, pow или from math import *,Весь модуль math загружается в любом случае, и после оператора импорта он присутствует в sys.modules.Таким образом, это не значит, что для загрузки требуется больше или меньше работы в зависимости от того, как вы ее импортируете.

Единственное различие между этими конструкциями заключается в создании в области импорта ссылок.к именам, которые вы упоминаете в операторе импорта.

import math, вероятно, самый дешевый оператор сам по себе , поскольку он загружает модуль и просто добавляет локальную ссылку на объект модуля втекущая сфера применения;по сути, это сводится к выполнению

math = __import__('math')

Однако каждое использование будет более дорогостоящим, так как math.sin потребуется два поиска в режиме dict (один LOAD_GLOBAL и один LOAD_ATTR), если import находился в глобальной области видимости, или один поиск локальной переменной (LOAD_FAST) + один поиск в двоичном формате (LOAD_ATTR) (если он был импортирован локально в функцию) для фактического достижения объекта функции для вызова.

from math import sqrt, pow будет стоить немного дороже, так как для него потребуется загрузить модуль, найдите в нем sqrt и pow (два поиска в dict) и создайте соответствующие записи в области, в которую вы их импортировали (если в двухкратном назначении)в глобальной области видимости два STORE_FAST локальных назначения, если в области видимости функции).Это эквивалентно чему-то вроде:

__temp = __import__('math')
sqrt = __temp.sqrt
pow = __temp.pow
del __temp

(__temp на самом деле не существует, это будет просто объект в стеке; sqrt и pow будут локальными или глобальными в зависимости отгде был введен оператор import)

С другой стороны, при поиске это будет быстрее, так как для него требуется только один поиск в dict (LOAD_GLOBAL для глобального импорта) или один локальный поиск (LOAD_FAST для локального импорта в функцию) по сравнению с двумя приведенными выше.

from math import * - то же, что и выше, но для всех символов, представленных в списке модуля __all__ (или всех предоставленных символовпо периоду модуля, если не указано __all__).

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

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

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

import math

def plot_it(framebuffer):
    sin = math.sin
    cos = math.cos
    for y in range(1024):
        for x in range(1024):
            framebuffer[y][x] = int(127*(sin(x)+cos(2*y)))

обычно будет быстрее, чем делать math.sin и math.cos на каждой итерации или даже импортировать sin и cos на верхнем уровне в файле и использовать ихпрямо в цикле, так как они, соответственно, два или один продиктованный поиск (для каждой итерации), в то время как здесь интерпретатору просто нужно загрузить два локальных объекта во внутреннем цикле (что очень быстро, это просто прямая загрузка массива)).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...