比较:import 语句与 __import__ 函数 [英] Comparison: import statement vs __import__ function

查看:52
本文介绍了比较:import 语句与 __import__ 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为问题在正常情况下使用内置__import__()的后续,我进行了几次测试,结果出人意料.

我在这里比较了一个经典的 import 语句和对 __import__ 内置函数的调用的执行时间.为此,我在交互模式下使用以下脚本:

导入时间定义测试(模块):t1 = timeit.timeit("import {}".format(module))t2 = timeit.timeit("{0} = __import__('{0}')".format(module))打印(导入语句:",t1)打印(__import__函数:",t2)print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))

在链接的问题中,这里是导入 sys 以及其他一些标准模块时的比较:

<预><代码>>>>测试('系统')导入语句:0.319865173171288__import__ 函数:0.38428380458522987t(语句)

到目前为止一切顺利,import__import__() 快.这对我来说很有意义,因为正如我在链接帖子中所写的那样,我发现 IMPORT_NAME 指令与 CALL_FUNCTION 相比被优化是合乎逻辑的,当后者导致调用 __import__.

但是当涉及到不那么标准的模块时,结果相反:

<预><代码>>>>测试('麻木')导入语句:0.18907936340054476__import__ 函数:0.15840019037769792t(语句)>t(函数)>>>测试('tkinter')导入语句:0.3798560809537861__import__ 函数:0.15899962771786136t(语句)>t(函数)>>>测试(pygame")导入语句:0.6624641952621317__import__ 函数:0.16268579177259568t(语句)>t(函数)

执行时间差异背后的原因是什么?import 语句在标准模块上更快的实际原因是什么?另一方面,为什么 __import__ 函数与其他模块一起更快?

使用 Python 3.6 进行测试

解决方案

timeit 衡量的是总执行时间,但是模块的第一次导入,无论是通过 import 还是__import__,比后续的要慢——因为它是唯一一个实际执行模块初始化的.它必须在文件系统中搜索模块的文件,加载模块的源代码(最慢)或之前创建的字节码(慢但比解析 .py 文件快一点)或共享库(对于 C 扩展),执行初始化代码,并将模块对象存储在 sys.modules 中.后续导入将跳过所有这些并从 sys.modules 中检索模块对象.

如果你颠倒顺序,结果就会不同:

导入时间定义测试(模块):t2 = timeit.timeit("{0} = __import__('{0}')".format(module))t1 = timeit.timeit("import {}".format(module))打印(导入语句:",t1)打印(__import__函数:",t2)print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))测试('麻木')导入语句:0.4611093703134608__import__ 函数:1.275512785926014t(语句)

获得无偏见结果的最佳方法是导入一次,然后进行计时:

导入时间定义测试(模块):exec("import {}".format(module))t2 = timeit.timeit("{0} = __import__('{0}')".format(module))t1 = timeit.timeit("import {}".format(module))打印(导入语句:",t1)打印(__import__函数:",t2)print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))测试('麻木')导入语句:0.4826306561727307__import__ 函数:0.9192819125911029t(语句)

所以,是的,import 总是比 __import__ 快.

As a followup to the question Using builtin __import__() in normal cases, I lead a few tests, and came across surprising results.

I am here comparing the execution time of a classical import statement, and a call to the __import__ built-in function. For this purpose, I use the following script in interactive mode:

import timeit   

def test(module):    
    t1 = timeit.timeit("import {}".format(module))
    t2 = timeit.timeit("{0} = __import__('{0}')".format(module))
    print("import statement:   ", t1)
    print("__import__ function:", t2)
    print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))

As in the linked question, here is the comparison when importing sys, along with some other standard modules:

>>> test('sys')
import statement:    0.319865173171288
__import__ function: 0.38428380458522987
t(statement) < t(function)

>>> test('math')
import statement:    0.10262547545597034
__import__ function: 0.16307580163101054
t(statement) < t(function)

>>> test('os')
import statement:    0.10251490255312312
__import__ function: 0.16240755669640627
t(statement) < t(function)

>>> test('threading')
import statement:    0.11349136644972191
__import__ function: 0.1673617034957573
t(statement) < t(function)

So far so good, import is faster than __import__(). This makes sense to me, because as I wrote in the linked post, I find it logical that the IMPORT_NAME instruction is optimized in comparison with CALL_FUNCTION, when the latter results in a call to __import__.

But when it comes to less standard modules, the results reverse:

>>> test('numpy')
import statement:    0.18907936340054476
__import__ function: 0.15840019037769792
t(statement) > t(function)

>>> test('tkinter')
import statement:    0.3798560809537861
__import__ function: 0.15899962771786136
t(statement) > t(function)

>>> test("pygame")
import statement:    0.6624641952621317
__import__ function: 0.16268579177259568
t(statement) > t(function)

What is the reason behind this difference in the execution times? What is the actual reason why the import statement is faster on standard modules? On the other hand, why is the __import__ function faster with other modules?

Tests lead with Python 3.6

解决方案

timeit measures the total execution time, but the first import of a module, whether through import or __import__, is slower than subsequent ones - because it's the only one that actually performs module initialization. It has to search the filesystem for the module's file(s), load the module's source code (slowest) or previously created bytecode (slow but a bit faster than parsing the .py files) or shared library (for C extensions), execute the initialization code, and store the module object in sys.modules. Subsequent imports get to skip all that and retrieve the module object from sys.modules.

If you reverse the order the results will be different:

import timeit   

def test(module):    
    t2 = timeit.timeit("{0} = __import__('{0}')".format(module))
    t1 = timeit.timeit("import {}".format(module))
    print("import statement:   ", t1)
    print("__import__ function:", t2)
    print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))

test('numpy')
import statement:    0.4611093703134608
__import__ function: 1.275512785926014
t(statement) < t(function)

The best way to get non-biased results is to import it once and then do the timings:

import timeit   

def test(module):    
    exec("import {}".format(module))
    t2 = timeit.timeit("{0} = __import__('{0}')".format(module))
    t1 = timeit.timeit("import {}".format(module))
    print("import statement:   ", t1)
    print("__import__ function:", t2)
    print("t(statement) {} t(function)".format("<" if t1 < t2 else ">"))

test('numpy')
import statement:    0.4826306561727307
__import__ function: 0.9192819125911029
t(statement) < t(function)

So, yes, import is always faster than __import__.

这篇关于比较:import 语句与 __import__ 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆