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
Why is there so much difference in class creation time using different versions of python? Tested on the same machine:
timeit
disables the garbage collector, which would otherwise break the cycles that keep a class object alive. Thus none of the classes gets deallocated until after timeit
has finished.
object.__subclasses__()
references these classes via an internal collection of weak references. The old list-based implementation of tp_subclasses
searches the entire list each time to find a dead reference that can be replaced. This process takes more time with each additional subclass. On the other hand, the new dict-based design in 3.4 can add a reference in constant time. See issue 17936.
Thanks to @MichaelYounkin for pointing out how this is also slow in 3.2. Initially I tried to narrow the performance difference to a change in the small-object allocator between 2.x and 3.x, but after reading his comment I discovered that even 3.3 was considerably slower than 3.4. So I scanned over the typeobject.c filelog to review recent changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With