为什么在python 2.7和python 3.4性能中创建类之间存在差异

Igo*_*gor 9 python performance python-2.7 python-3.x

from timeit import Timer as T

def calc(n):
    return T("class CLS(object): pass").timeit(n)

print(calc(90000))
print(calc(90000))
print(calc(90000))

# python3.4
1.1714721370008192
1.0723806529986177
1.111804607000522

# python2.7
15.7533519268
16.7191421986
16.8397979736
Run Code Online (Sandbox Code Playgroud)

为什么使用不同版本的python在类创建时间上有这么大的差异?在同一台机器上测试:

  • i5-3450 CPU @ 3.10GHz
  • 8gb ram

小智 0

好吧,问题似乎出在 python 2.7 中的旧式类与新式类之间。

在 python 3.4 中你可以看到使用 object 和不使用 object 之间的区别只是符号的加载(不是那么重要):

C:\TEMP>C:\Python34\python.exe
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> def a():
...   class A(object): pass
...
>>> def b():
...   class B(): pass
...
>>> import dis
>>> dis.dis(a)
  2           0 LOAD_BUILD_CLASS
              1 LOAD_CONST               1 (<code object A at 0x020B8F20, file "<stdin>", line 2>)
              4 LOAD_CONST               2 ('A')
              7 MAKE_FUNCTION            0
             10 LOAD_CONST               2 ('A')
             13 LOAD_GLOBAL              0 (object)   # Extra step, not that expensive.
             16 CALL_FUNCTION            3 (3 positional, 0 keyword pair)
             19 STORE_FAST               0 (A)
             22 LOAD_CONST               0 (None)
             25 RETURN_VALUE
>>> dis.dis(b)
  2           0 LOAD_BUILD_CLASS
              1 LOAD_CONST               1 (<code object B at 0x020B8D40, file "<stdin>", line 2>)
              4 LOAD_CONST               2 ('B')
              7 MAKE_FUNCTION            0
             10 LOAD_CONST               2 ('B')
             13 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             16 STORE_FAST               0 (B)
             19 LOAD_CONST               0 (None)
             22 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)

在 Python 2.7 上,您还有另一个涉及 LOAD_TUPLE 的步骤:

C:\Users\jsargiot\Downloads\so>C:\Python27\python.exe
Python 2.7.8 (default, Jun 30 2014, 16:03:49) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> def a():
...   class A(object): pass
...
>>> def b():
...   class B(): pass
...
>>> import dis
>>> dis.dis(a)
  2           0 LOAD_CONST               1 ('A')
              3 LOAD_GLOBAL              0 (object)   # First extra step (just like 3.4)
              6 BUILD_TUPLE              1            # Second extra step, expensive
              9 LOAD_CONST               2 (<code object A at 01EAEA88, file "<stdin>", line 2>)
             12 MAKE_FUNCTION            0
             15 CALL_FUNCTION            0
             18 BUILD_CLASS
             19 STORE_FAST               0 (A)
             22 LOAD_CONST               0 (None)
             25 RETURN_VALUE
>>> dis.dis(b)
  2           0 LOAD_CONST               1 ('B')
              3 LOAD_CONST               3 (())
              6 LOAD_CONST               2 (<code object B at 01EB8EC0, file "<stdin>", line 2>)
              9 MAKE_FUNCTION            0
             12 CALL_FUNCTION            0
             15 BUILD_CLASS
             16 STORE_FAST               0 (B)
             19 LOAD_CONST               0 (None)
             22 RETURN_VALUE
>>>
Run Code Online (Sandbox Code Playgroud)