Marvelous
Marvelous

Reputation: 21

Python Inheritance Performance Cost

I have multiple inheritance layers and I am trying to understand if this could not lead to a performance issue due to the multiple calls. Here is also a small example to illustrate it:

class MySuperClass:
    def __init__(self, arg1):
        self.arg1 = arg1


class MyFirstSubClass(MySuperClass):
    def __init__(self, arg1, arg2):
        super().__init__(arg1)
        self.arg2 = arg2

class MySecondSubClass(MyFirstSubClass):
    def __init__(self, arg1, arg2, arg3):
        super().__init__(arg1, arg2)
        self.arg3 = arg3

How does Python work here. Are the super calls executed every time the objects are created?

Upvotes: 1

Views: 480

Answers (1)

Tom McLean
Tom McLean

Reputation: 6327

Yes. super() is called.

%%timeit
x = MySecondSubClass(0, 1, 2)
9.97 µs ± 484 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

vs:

class NoInheritance:
    def __init__(self, arg1, arg2, arg3):
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3

Time:

%%timeit
x = NoInheritance(0, 1, 2)
4.31 µs ± 333 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

And using slots:

class NoIneritance:
    __slots__ = ["arg1", "arg2", "arg3"]
    def __init__(self, arg1, arg2, arg3):
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3

%%timeit
x = NoIneritance(0, 1, 2)
2.56 µs ± 152 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

And if you don't need any methods on your class, you can use a named tuple:

from collections import namedtuple
no_inheritance = namedtuple("no_inheritance", ["arg1", "arg2", "arg3"])

%%timeit
x = no_inheritance(0, 1, 2)
1.11 µs ± 8.34 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

Upvotes: 1

Related Questions