0

Say there is a class:

class x(obj):
    y = 1

What is faster (or preferred):

    def __init__(self):
        print self.y

or:

    def __init__(self):
        print x.y

I assume x.y better communicates the intend but I'm interested in the speed implications.

Ecir Hana
  • 10,864
  • 13
  • 67
  • 117
  • 5
    Why don't you just measure it? The `timeit` module is your friend. My guess is that the latter version is faster, since it will skip the instance look-up, but the difference is probably small. Go for the semantics you need, unless you *really* need the performance. – Sven Marnach Jul 19 '12 at 10:56
  • 5
    In the grand scheme of things that can affect the speed of your code, wondering about access "speed" of class variables is way down the list; if on it at all. – Burhan Khalid Jul 19 '12 at 10:58
  • https://stackoverflow.com/questions/2714573/instance-variables-vs-class-variables-in-python/52777427#52777427 https://stackoverflow.com/questions/10703605/performance-of-accessing-class-variables-in-python/ – robertcollier4 Oct 12 '18 at 10:45

2 Answers2

3

The performance gain you could possibly achieve with these micro optimizations doesn't matter. The impact of the printing dwarfs the cost of attribute access by far. For reference, here's a test script:

import sys,timeit
class ClassAccess(object):
    y = 1
    def __init__(self):
        print(ClassAccess.y)

class SelfAccess(object):
    y = 1
    def __init__(self):
        print(self.y)

ca = timeit.timeit(ClassAccess, number=100000)
sa = timeit.timeit(SelfAccess, number=100000)

sys.stderr.write(str(ca) + "\n")
sys.stderr.write(str(sa) + "\n")

On my machine (with the yakuake terminal), this outputs

0.640013933182
0.628859043121

This is within experimental error of both variants being identical. Crude experimentation shows that:

  • Approximately 90% of the runtime is caused by actually displaying the printed result.
  • Of the rest, approximately 50% is the time that the print statement alone takes up.
  • Approximately 80% of the rest of that is caused by the allocation of the objects.

Therefore, it's safe to say to derive the conclusion that there is no difference in performance.

phihag
  • 278,196
  • 72
  • 453
  • 469
  • If I replace `print` with 'z =', the first one is slightly faster. Thanks. – Ecir Hana Jul 19 '12 at 11:07
  • 2
    It __does__ matter. Not in terms in performance, but `self.y` __is__ the preferred method. It's easier to maintain (if the class name changes no need to change all functions), and it allows overriding of the class-wide value if needed. – orlp Jul 19 '12 at 11:11
  • 1
    @Ecir Hana: oh and let's not forget overriding through inheritance. – orlp Jul 19 '12 at 11:14
0

Note that depending on the class implementation the returned values may differ.

This returns the y attribute of the instance :

def __init__(self):
    print self.y

While this returns the y attribute of the class :

def __init__(self):
    print x.y

If the constructor override the y attribute a la :

def __init__(self, y=None):
    self.y = y
def print(self):
    print self.y

the returned values will differ. Python looks up the instance internal dictionary checking for y before to check for the class internat dictionary. So I think that print x.y should be slightly faster because it avoids looking up the instance dictionary.

Nicolas Barbey
  • 6,639
  • 4
  • 28
  • 34