Runtime: Instance methods vs classmethods (Python)

17 Views Asked by At

I am interested in the runtime difference between instance methods and classmethods in Python.

Problem

I have a file main.py which loops through the lines of a file (more than 1 million lines). There are several methods that get called for each line. I outsourced these methods in another file line.py within a class LineStuff. Now I import LineStuff in main.py and call several methods for each line.

Since LineStuff does not need to have any states I first implemented all the methods as *classmethods *(class variables are needed, i.e. staticmethod would not work).

But a simple test (see below) suggest that using classmethods is actually slower.

Question: Is that actually the case and if yes, why is that?

Test

For the purpose of testing I created a file main.py that runs the imported methods and measures the runtime of each approach. In the file line.py there are a class for instance methods, *classmethods *and *staticmethods *respectively, which just calculate the square of a given number.

main.py

from line import Standard, Class, Static
import timeit

def runtime(classtype:str, cnt:int = 10000000, value:int = 1000):
    
    start = timeit.default_timer()

    if classtype == "standard":
        x = Standard()
        for _ in range(cnt):
            x.method(1000)
    elif classtype == "class":
        for _ in range(cnt):
            Class.method(1000)
    elif classtype == "static":
        for _ in range(cnt):
            Static.method(1000)
    
    end = timeit.default_timer()
    
    return round(end - start, 2)


if __name__ == "__main__":
    
    runtimes = {
        "standard": runtime("standard"),
        "class": runtime("class"),
        "static": runtime("static"),
    }
    
    print(runtimes)

line.py

class Standard:
    
    def __init__(self) -> None:
        pass
    
    def method(self, number):
        return number ** 2
    
    
class Class:
    
    def __init__(self) -> None:
        pass
    
    @classmethod
    def method(cls, number):
        return number ** 2
    
    
class Static:
    
    def __init__(self) -> None:
        pass
    
    @staticmethod
    def method(number):
        return number ** 2

Result

The output yields: {'standard': 2.58, 'class': 4.02, 'static': 3.25}

0

There are 0 best solutions below