Skip to content Skip to sidebar Skip to footer

Using Builtin __import__() In Normal Cases

Here is where I checked the performance of __import__() In [9]: %%timeit ...: math = __import__('math') ...: sqrt = math.sqrt ...: sqrt(7894561230) ...: The slowest ru

Solution 1:

Here is a small "benchmark". Let's define two functions:

def f1():
    import sys

def f2():
    sys = __import__('sys')

Bytecode comparison:

>>> dis.dis(f1)
  5           0 LOAD_CONST               1 (0)
              2 LOAD_CONST               0 (None)
              4 IMPORT_NAME              0 (sys)
              6 STORE_FAST               0 (sys)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

>>> dis.dis(f2)
  8           0 LOAD_GLOBAL              0 (__import__)
              2 LOAD_CONST               1 ('sys')
              4 CALL_FUNCTION            1
              6 STORE_FAST               0 (sys)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE

The generated bytecodes have the same number of instructions, but they are different. So what about the timing?

>>> timeit.timeit(f1)
0.4096750088112782

>>> timeit.timeit(f2)
0.474958091968411

It turns out that the __import__ way is slower. In addition, it is far less readable than the classical import statement.

Conclusion: stick with import.


Now for a bit of interpretation...

I suppose that calling __import__ is slower than executing an import statement, because the bytecode generated by the latter is optimised.

Take a look at the instructions: the bytecode for __import__ just look like any other function call, with a CALL_FUNCTION instruction. On the other hand, the import statement results in a IMPORT_NAME instruction, which definetely looks like something dedicated to imports, and is probably executed in an optimised way by the interpreter.

As a matter of fact, the third instruction is the only true difference between the two bytecodes. So the difference between the two functions lies in the difference between IMPORT_NAME and CALL_FUNCTION.


Post a Comment for "Using Builtin __import__() In Normal Cases"