【问题标题】:Most Performant Way To Do Imports最高效的导入方式
【发布时间】:2016-11-06 09:22:49
【问题描述】:

从性能的角度(时间或内存)来看,这样做更好:

import pandas as pd

from pandas import DataFrame, TimeSeries

最好的办法取决于我从包中导入了多少类?

同样,我见过人们做这样的事情:

def foo(bar):
    from numpy import array

我为什么要在函数或方法定义中进行导入?这是否意味着每次调用该函数时都会执行导入?或者这只是为了避免命名空间冲突?

【问题讨论】:

  • 从函数导入的一个想法是避免在未调用函数时导入(可能已卸载)模块。

标签: python


【解决方案1】:

这是微优化,您不必担心。

每个 Python 进程都会加载一次模块。然后导入的所有代码只需要将名称绑定到模块或模块中定义的对象。这种绑定非常便宜

此外,your 模块中的顶级代码也只运行一次,因此绑定只发生一次。每次运行函数时,函数中的导入都会进行绑定,但同样,这非常便宜,可以忽略不计。

在函数中导入会产生不同的原因有两个:它不会将该名称放入模块的全局命名空间中(因此不会污染命名空间),并且因为该名称现在是 local,使用该名称比使用全局名称稍快。

如果您想提高性能,请关注重复多次的代码。导入不是。

【讨论】:

  • 干杯。我实际上并不打算使用它来改进任何真实的代码。这只是学术上的好奇心。
【解决方案2】:

回答何时导入这个更一般的问题,导入是依赖项。程序运行所需的代码可能存在也可能不存在。因此,最好尽快导入该代码,以防止在执行过程中出现愚蠢的错误。

当 pypy 变得越来越流行时尤其如此,当导入可能存在但不能通过 pypy 使用时。尽早失败要好得多,而不是在代码执行几个小时后失败。

至于“import pandas as pd”与“from pandas import DataFrame, TimeSeries”,这个问题有多个问题(就像所有问题一样),其中一些问题比其他问题重要得多。有命名空间的问题,有可读性的问题,还有性能的问题。正如 Martjin 所说,性能应该对决策做出大约 0.0001% 的贡献。可读性应占 90% 左右。命名空间只有 10%,因为它可以很容易地缓解。

在我个人看来,import X as Yform X import Y 都是不好的做法,因为显式优于隐式。您不想在第 2000 行试图记住“calculate_mean”来自哪个包,因为在代码中的其他任何地方都没有引用它。当我第一次开始使用 numpy 时,我正在从互联网上复制/粘贴代码,但不知道为什么我没有/不能pip install np。如果您预先知道“np”是“numpy”的python,这显然不是问题,但是对于它保存的3个字母来说,这是一个愚蠢且毫无意义的混淆。它来自 numpy。使用 numpy。

【讨论】:

    【解决方案3】:

    在尚未提及的函数中导入模块的好处是:这样做可以让您对何时加载模块进行一些控制。事实上,尽管@J.J 的回答建议尽早导入所有模块,但此控件允许您推迟 加载模块。

    您为什么要这样做?好吧,虽然它不会提高程序的实际性能,但这样做可以提高感知性能,并因此改善用户体验

    在某种程度上,用户会根据启动所需的时间来判断您的应用是快还是慢。

    MSDN: Best practices for your app's startup performance

    在主脚本的开头加载每个模块可能需要一些时间。例如,我的一个应用程序使用 Qt 框架、Pandas、Numpy 和 Matplotlib。如果所有这些模块都是在应用程序开始时导入的,则用户界面的出现会延迟几秒钟。用户不喜欢等待,他们可能会因为这种等待而认为您的应用程序通常很慢​​。

    但是,例如,如果 Matplotlib 仅从用户发出绘图命令时调用的那些函数中导入,则启动时间会显着减少。用户不会再觉得您的应用那么迟钝,这可能会带来更好的用户体验。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2010-11-22
      • 2019-11-27
      相关资源
      最近更新 更多