如果我要使用至少两种方法的库,下面两种方式的性能和内存使用有区别吗?
from X import method1, method2
并且。
import X
如果我要使用至少两种方法的库,下面两种方式的性能和内存使用有区别吗?
from X import method1, method2
import X
两者有所不同,因为使用import x
版本时需要进行两次名称查找:一次是模块名的查找,另一次是函数名的查找;而使用from x import y
则只需要一次查找。
您可以使用dis
模块清楚地看到这一点:
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
更快。
话虽如此,像往常一样,我建议你不要根据这种知识决定如何导入模块和函数,因为这只是一些过早的优化。
个人认为,在许多情况下,显式命名空间更易读,我建议您做同样的事情:使用自己的美学感觉 :-)
没有内存或速度上的区别(因为整个模块都必须进行评估,因为最后一行代码可能是Y = something_else
)。除非你的电脑是20世纪80年代的,否则无论如何都不重要。
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)
import x
比from x import y
更快,这似乎与查看dis.dis
后的预期相反。相当好奇。 - unutbufrom x import y
更快(p 别名为 python2.6): p -m timeit "import random; random.seed()" 10000 次循环,3次中的最佳结果:每次27.7微秒。 p -m timeit "from random import seed; seed()" 10000 次循环,3次中的最佳结果:每次29.2微秒。在 3.1 中进行相同的测试,结果类似。 - Sam Dolan