Подтвердить что ты не робот

Импорт Python X или из X import Y? (представление)

Мне просто интересно - если есть библиотека, из которой я собираюсь использовать как минимум 2 метода, есть ли разница в производительности или использовании ram между: из X import method1, method2 и это импорт X Я знаю об пространствах имен и т.д., Но мне просто интересно, достаточно ли для Python достаточно знать, что я буду использовать только 2 метода.

4b9b3361

Ответ 1

Есть разница, потому что в версии import x есть два поиска имен: один для имени модуля и второй для имени функции; с другой стороны, используя from x import y, у вас есть только один поиск.

Вы можете увидеть это достаточно хорошо, используя этот модуль:

import random
def f_1():
    random.seed()

dis.dis(f_1)
     0 LOAD_GLOBAL              0 (random)
     3 LOAD_ATTR                0 (seed)
     6 CALL_FUNCTION            0
     9 POP_TOP
    10 LOAD_CONST               0 (None)
    13 RETURN_VALUE

from random import seed

def f_2():
    seed()

dis.dis(f_2)
     0 LOAD_GLOBAL              0 (seed)
     3 CALL_FUNCTION            0
     6 POP_TOP
     7 LOAD_CONST               0 (None)
    10 RETURN_VALUE

Как вы можете видеть, использование формы from x import y выполняется немного быстрее.

С другой стороны, import x дешевле, чем from x import y, потому что там меньше меньше имен; посмотрим на дизассемблированный код:

def f_3():
    import random

dis.dis(f_3)
     0 LOAD_CONST               1 (-1)
     3 LOAD_CONST               0 (None)
     6 IMPORT_NAME              0 (random)
     9 STORE_FAST               0 (random)
    12 LOAD_CONST               0 (None)
    15 RETURN_VALUE

def f_4():
    from random import seed

dis.dis(f_4)
     0 LOAD_CONST               1 (-1)
     3 LOAD_CONST               2 (('seed',))
     6 IMPORT_NAME              0 (random)
     9 IMPORT_FROM              1 (seed)
    12 STORE_FAST               0 (seed)
    15 POP_TOP
    16 LOAD_CONST               0 (None)
    19 RETURN_VALUE

Я не знаю причину, но форма from x import y выглядит как вызов функции и, следовательно, даже дороже, чем ожидалось; по этой причине, если импортированная функция используется только один раз, это означает, что было бы быстрее использовать import x, а если она используется более одного раза, она становится быстрее использовать from x import y.

Это, как обычно, я предлагаю вам не следовать этим знаниям для вашего решения о том, как импортировать модули и функции, потому что это лишь некоторая преждевременная оптимизация. Лично я думаю, что во многих случаях явные пространства имен намного читабельнее, и я предлагаю вам сделать то же самое: использовать свое собственное чувство эстетики: -)

Ответ 2

Нет разницы в памяти или скорости (весь модуль должен быть оценен в любом случае, поскольку последняя строка может быть Y = something_else). Если ваш компьютер не с 1980-х годов, это не имеет никакого значения.

Ответ 3

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

Ответ 4

Это может иметь значение, если вы вызываете функцию много раз в цикле (миллионы и более). Выполнение поиска в двойном словаре в конечном итоге будет накапливаться. Пример ниже показывает увеличение на 20%.

Время, указанное для Python 3.4, на 64-битной машине Win7. (Измените команду range на xrange для Python 2.7).

Этот пример очень основан на книге High Performance Python, хотя их третий пример поиска локальных функций, которые лучше не выглядели, я.

import math
from math import sin

def tight_loop_slow(iterations):
    """
    >>> %timeit tight_loop_slow(10000000)
    1 loops, best of 3: 3.2 s per loop
    """
    result = 0
    for i in range(iterations):
        # this call to sin requires two dictionary lookups
        result += math.sin(i)

def tight_loop_fast(iterations):
    """
    >>> %timeit tight_loop_fast(10000000)
    1 loops, best of 3: 2.56 s per loop
    """
    result = 0
    for i in range(iterations):
        # this call to sin only requires only one lookup
        result += sin(i)