Skip to content Skip to sidebar Skip to footer

Why Is Creating A Class In Python So Much Slower Than Instantiating A Class?

I found that creation of a class is way slower than instantiation of a class. >>> from timeit import Timer as T >>> def calc(n): ... return T('class Haha(obje

Solution 1:

This might give you the intuition:

>>>classHaha(object): pass...>>>sys.getsizeof(Haha)
904
>>>sys.getsizeof(Haha())
64

Class object is much more complex and expensive structure than an instance of that class.

Solution 2:

Ahahaha! Gotcha!

Was this perchance done on a Python version without this patch? (HINT: IT WAS)

Check the line numbers if you want proof.

Marcin was right: when the results look screwy you've probably got a screwy benchmark. Run gc.disable() and the results reproduce themselves. It just shows that when you disable garbage collection you get garbage results!


To be more clear, the reason running the long benchmark broke things is that:

  • timeit disables garbage collections, so overly large benchmarks take much (exponentially) longer

  • timeit wasn't restoring garbage collection on exceptions

  • You quit the long-running process with an asynchronous exception, turning off garbage collection

Solution 3:

A quick dis of the following functions:

def a():
    classHaha(object):
         pass



def b():
    Haha()

gives:

20 LOAD_CONST               1 ('Haha')
            3 LOAD_GLOBAL              0 (object)
            6 BUILD_TUPLE              19 LOAD_CONST               2 (<code object Haha at 0x7ff3e468bab0, file "<stdin>", line 2>)
            12 MAKE_FUNCTION            015 CALL_FUNCTION            018 BUILD_CLASS         
            19 STORE_FAST               0 (Haha)
            22 LOAD_CONST               0 (None)
            25 RETURN_VALUE        

and

20 LOAD_GLOBAL              0 (Haha)
            3 CALL_FUNCTION            06 POP_TOP             
            7 LOAD_CONST               0 (None)
            10 RETURN_VALUE        

accordingly.

By the looks of it, it simply does more stuff when creating a class. It has to initialize class, add it to dicts, and wherever else, while in case of Haha() is just calls a function.

As you noticed doing garbage collection when it gets's too slow speeds stuff up again, so Marcin's right in saying that it's probably memory fragmentation issue.

Solution 4:

It isn't: Only your contrived tests show slow class creation. In fact, as @Veedrac shows in his answer, this result is an artifact of timeit disabling garbage collection.

Downvoters: Show me a non-contrived example where class creation is slow.

In any case, your timings are affected by the load on your system at the time. They are really only useful for comparisons performed at pretty much the same time. I get about 0.5s for 9000 class creations. In fact, it's about 0.3s on ideone, even when performed repeatedly: http://ideone.com/Du859. There isn't even an upward trend.

So, in summary, it is much slower on your computer than others, and there is no upwards trend on other computers for repeated tests (as per your original claim). Testing massive numbers of instantiations does show slowing down, presumably because the process consumes a lot of memory. You have shown that allocating a huge amount of memory slows a process down. Well done.

That ideone code in full:

from timeit import Timer as T
defcalc(n):
return T("class Haha(object): pass").timeit(n)

for i in xrange(30):
print calc(9000)

Post a Comment for "Why Is Creating A Class In Python So Much Slower Than Instantiating A Class?"