27

When I started learning Python, I created a few applications just using functions and procedural code. However, now I know classes and realized that the code can be much readable (and subjectively easier to understand) if I rewrite it with classes.

How much slower the equivalent classes may get compared to the functions in general? Will the initializer, methods in the classes make any considerable difference in speed?

Redowan Delowar
  • 1,580
  • 1
  • 14
  • 36
xralf
  • 3,312
  • 45
  • 129
  • 200
  • It's probably going to depend some on how you implement it and what your functions do. You could do some tests yourself with the timing module. – Kris Harper Dec 13 '11 at 16:33
  • The question is far to general to be answered meaningfully. This will vary tremendously from use case to use case. Just try it and measure. Also make sure that performance is actually an issue. – Sven Marnach Dec 13 '11 at 16:34
  • 4
    if the performance hit (if any) from using classes was of any significance to you then you probably shouldn't be using python in the first place. Dont worry about such a small detail. Code readability is a much more important factor than performance in 99% of cases. – soulcheck Dec 13 '11 at 16:36
  • 3
    And in case you're wondering how to measure it: http://docs.python.org/library/timeit.html – kojiro Dec 13 '11 at 16:36
  • 1
    You're using Python and you're worrying about performance on such a level? It isn't, especially not in general. But even if everything ran 2x slower with classes, all the other advantages would make it more than worth it. –  Dec 13 '11 at 16:37
  • @delnan I'm not warying, I'm only interested what's the cost of readability and this level of abstraction. – xralf Dec 13 '11 at 17:09

4 Answers4

48

To answer the question: yes, it is likely to be a little slower, all else being equal. Some things that used to be variables (including functions) are now going to be object attributes, and self.foo is always going to be slightly slower than foo regardless of whether foo was a global or local originally. (Local variables are accessed by index, and globals by name, but an attribute lookup on an object is either a local or a global lookup, plus an additional lookup by name for the attribute, possibly in multiple places.) Calling a method is also slightly slower than calling a function -- not only is it slower to get the attribute, it is also slower to make the call, because a method is a wrapper object that calls the function you wrote, adding an extra function call overhead.

Will this be noticeable? Usually not. In rare cases it might be, say if you are accessing an object attribute a lot (thousands or millions of times) in a particular method. But in that case you can just assign self.foo to a local variable foo at the top of the method, and reference it by the local name throughout, to regain 99.44% of the local variable's performance advantage.

Beyond that there will be some overhead for allocating memory for instances that you probably didn't have before, but unless you are constantly creating and destroying instances, this is likely a one-time cost.

In short: there will be a likely-minor performance hit, and where the performance hit is more than minor, it is easy to mitigate. On the other hand, you could save hours in writing and maintaining the code, assuming your problem lends itself to an object-oriented solution. And saving time is likely why you're using a language like Python to begin with.

kindall
  • 178,883
  • 35
  • 278
  • 309
33

No.

In general you will not notice any difference in performance based on using classes or not. The different code structures implied may mean that one is faster than the other, but it's impossible to say which.

Always write code to be read, then if, and only if, it's not fast enough make it faster. Remember: Premature optimization is the root of all evil.

Andrew Wilkinson
  • 10,682
  • 3
  • 35
  • 38
  • 16
    -1 because of the certain No. Yes, readability is more important than small performance differences, but in CPython calling a method is clearly slower than calling a global function, same as creating an object is slower than creating a map. The differences are very small, but classes are still slower than the classless alternatives. – Dakkaron Aug 19 '16 at 11:32
  • 1
    @Dakkaron, I think you might be right. I just posted this after finding out that the same exact function using a class as a wrapper for the native list data structure was twice as slow: http://stackoverflow.com/questions/41781048/overhead-of-creating-classes-in-python-exact-same-code-using-class-twice-as-slo – jeremy radcliff Jan 21 '17 at 15:29
12

Donald Knuth, one of the grand old minds of computing, is credited with the observation that "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." Deciding to use procedural techniques rather than object-oriented ones on the basis of speed gains that may well not be realized anyway is not a sensible strategy.

If your code works and doesn't need to be modified then feel free to leave it alone. If it needs to be modified then you should consider a judicious refactoring to include classes, since program readability is far more important than speed during development. You will also see benefits in improved maintainability. An old saw from Kernighan and Plauger's "Elements of Programming Style" still applies:

First, make it work. Then (if it doesn't work fast enough) make it work faster.

But, first and foremost, go for readability. Seriously.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • After reading this text, I logged in and performed the +1 process. My view is that class variables get ugly in IO operations (definitely not recommended if you have more than 500us processing time). Respects, love. – dsgdfg Mar 26 '22 at 12:07
  • Thank you. I'm not sure what specific issues you're referring to, but class variables have their places (default instance values is one, program telemetry is another). – holdenweb Mar 27 '22 at 11:24
7

You probably don't care as much as you think you do.

Really.

Sure, code with classes might be a little slower through indirection. Maybe. That is what JIT compilation is for, right? I can never remember which versions of python do this and which don't, because:

Performance doesn't matter.

At least constant performance differences like this. Unless you are doing a hell of a lot of computations (you aren't!), you will spend more time developing/debugging/maintaining your code. Optimize for that.

Really. Because you will never ever be able to measure the difference, unless you are in a tight loop. And you don't want to be doing that in python anyway, unless you don't really care about time. It's not like you're trying to balance your segway in python, right? You just want to compute some numbers, right? Your computer is really good at this. Trust it.

That said, this doesn't mean classes are the way to go. Just that speed isn't the question you should be asking. Instead, try to figure out what representation will be the best for your code. It seems, now you know classes, you will write clean code in OO fashion. Go ahead. Learn. Iterate.

Daren Thomas
  • 67,947
  • 40
  • 154
  • 200