【问题标题】:Python - Performance difference between importing a function and locally declaring it?Python - 导入函数和本地声明函数之间的性能差异?
【发布时间】:2018-07-11 09:23:07
【问题描述】:

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

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

【问题讨论】:

  • 通话中没有额外的开销。但真的,谁在乎呢?我们不使用 Python 来获得超级机器效率。我们用它来提高程序员的效率。

标签: python performance runtime


【解决方案1】:

您好 Jet Blue 以便更好地理解 python wiki PerformanceTips

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

考虑以下两个 sn-ps 代码(我相信最初来自 Greg McFarlane - 我发现它在 comp.lang.python python-list@python.org 帖子中没有归属,后来在另一个来源中归属于他):

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()

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

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

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

def doit3():
    'Python'.lower()

for num in range(100000):
    doit3()

这是来自 timeit 的证明:

def doit3(): 'Python'.lower()

t = timeit.Timer(setup='from ma​​in import doit3', stmt='doit3()') t.timeit() 2.5606080293655396

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

请注意,将导入放入函数中可以加快模块的初始加载速度,尤其是在可能不需要导入的模块时。这通常是一种“惰性”优化的情况——避免工作(导入模块,这可能非常昂贵),直到您确定需要它。

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

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

email = None

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

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

【讨论】:

    【解决方案2】:

    我怀疑调用本地声明的函数与导入的函数之间应该有区别。虽然,正在执行的代码行与为执行相同代码而调用的函数之间存在细微差别。 This 应该会有所帮助,以防我对我的措辞有点困惑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      • 2011-10-11
      • 2021-09-17
      • 2023-02-07
      • 2015-03-11
      • 1970-01-01
      • 2014-06-29
      相关资源
      最近更新 更多