Python—导入函数和在本地声明函数之间的性能差异?

Python—导入函数和在本地声明函数之间的性能差异?,python,performance,runtime,Python,Performance,Runtime,在Python中导入函数与在当前文件中声明函数在性能上是否存在显著差异 我有一个小函数(一行程序),我经常在程序中的几个.py文件中使用它。相反,我希望对它进行一次定义,以便我对它所做的更改能够反映到所有地方。但是,我不确定将其作为导入函数使用是否会在调用它时增加额外的开销 Hi Jet Blue可帮助您更好地理解 导入语句几乎可以在任何地方执行。将它们放在函数中以限制其可见性和/或减少初始启动时间通常很有用。尽管Python的解释器经过优化,不会多次导入同一模块,但在某些情况下,重复执行imp

在Python中导入函数与在当前文件中声明函数在性能上是否存在显著差异


我有一个小函数(一行程序),我经常在程序中的几个.py文件中使用它。相反,我希望对它进行一次定义,以便我对它所做的更改能够反映到所有地方。但是,我不确定将其作为导入函数使用是否会在调用它时增加额外的开销

Hi Jet Blue可帮助您更好地理解

导入语句几乎可以在任何地方执行。将它们放在函数中以限制其可见性和/或减少初始启动时间通常很有用。尽管Python的解释器经过优化,不会多次导入同一模块,但在某些情况下,重复执行import语句可能会严重影响性能

考虑以下两段代码(我相信最初来自Greg McFarlane,我发现它在comp.lang.python中没有被分配)-list@python.org发布并随后在另一来源中归因于他):

或:

doit2将比doit1运行得快得多,即使doit2中对字符串模块的引用是全局的。下面是使用Python 2.3和新的timeit模块运行的Python解释器会话,它显示了第二个解释器比第一个解释器快多少:

Python 2.0中的语言引入了字符串方法。这提供了一个完全避免导入并运行更快的版本:

这是来自timeit的证据:

def doit3(): Python.lower()

t=timeit.Timer(setup='frommainimport doit3',stmt='doit3() t、 timeit() 2.5606080293655396

上面的例子显然有点做作,但一般原则是成立的

请注意,将导入放在函数中可以加快模块的初始加载,特别是在可能不需要导入的模块的情况下。这通常是一种“惰性”优化——在确定需要之前避免工作(导入模块,这可能非常昂贵)

这只是在模块根本不会被导入(从任何模块)的情况下的一个显著节省——如果模块已经被加载(对于许多标准模块,如string或re,情况就是这样),避免导入不会为您节省任何东西。要查看系统中加载了哪些模块,请查看sys.modules

执行惰性导入的一个好方法是:

这样,在第一次调用parse_email()时,电子邮件模块将只导入一次


我怀疑对本地声明的函数的调用与导入的函数之间应该有区别。尽管如此,正在执行的代码行与为执行相同代码而调用的函数之间还是有一点区别。如果我的措辞有点混乱,应该会有所帮助。

通话中没有额外的开销。但真的,谁在乎呢?我们使用Python并不是为了实现超级机器效率。我们使用它来提高编程效率。
def doit1():
    import string ###### import statement inside function
    string.lower('Python')

for num in range(100000):
    doit1()
import string ###### import statement outside function
def doit2():
    string.lower('Python')

for num in range(100000):
    doit2()
def doit1():
    import string
    string.lower('Python')

import string
def doit2():
    string.lower('Python')

import timeit
t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
t.timeit()
11.479144930839539
t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
t.timeit()
4.6661689281463623
def doit3():
    'Python'.lower()

for num in range(100000):
    doit3()
email = None

def parse_email():
    global email
    if email is None:
        import email