@staticmethod vs instance method

Or when intuition is our enemy.

In one of the code reviews, I’ve noticed my colleague using instance method instead of a static method in our Python codebase and kindly asked him to switch to a static method because:

  • it clearly communicates that instance state cannot be changed which makes it easier to prove invariants

  • it’s faster… Right?

While the first point is not very contentious, the second one turned out to be not as obvious as I thought but fortunately it’s actually measurable, so let’s see…

Since instance methods accept an additional parameter self, I expected this to be a source of additional overhead and difference in bytecode, but for

both instance and static add methods result in identical bytecode

and their invocations are done in the exact same way via foo instance

and is only slightly different for an invocation via Foo class

with LOAD_GLOBAL being used instead of LOAD_FAST.

Having learnt this, it does not come as surprise that both invocations via instance method take the same amount of time

%timeit foo.instance_add(1,2)
10000000 loops, best of 5: 135 ns per loop

and

%timeit foo.static_add(1,2)
10000000 loops, best of 5: 139 ns per loop

And invocation via Foo class made no difference as well

%timeit Foo.static_add(1,2)
10000000 loops, best of 5: 139 ns per loop

As such my intuition was wrong and even though I still prefer using static methods when instance state does not have to be accessed, performance should not be used as a reason for this.