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
%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.