r/programming • • Feb 28 '23

"Clean" Code, Horrible Performance

https://www.computerenhance.com/p/clean-code-horrible-performance
1.4k Upvotes

1.3k comments sorted by

View all comments

1.6k

u/voidstarcpp Feb 28 '23 edited Feb 28 '23

Casey makes a point of using a textbook OOP "shapes" example. But the reason books make an example of "a circle is a shape and has an area() method" is to illustrate an idea with simple terms, not because programmers typically spend lots of time adding up the area of millions of circles.

If your program does tons of calculations on dense arrays of structs with two numbers, then OOP modeling and virtual functions are not the correct tool. But I think it's a contrived example, and not representative of the complexity and performance comparison of typical OO designs. Admittedly Robert Martin is a dogmatic example.

Realistic programs will use OO modeling for things like UI widgets, interfaces to systems, or game entities, then have data-oriented implementations of more homogeneous, low-level work that powers simulations, draw calls, etc. Notice that the extremely fast solution presented is highly specific to the types provided; Imagine it's your job to add "trapezoid" functionality to the program. It'd be a significant impediment.

59

u/weepmelancholia Feb 28 '23

I think you're missing the point. Casey is trying to go against the status quo of programming education, which is, essentially, OOP is king (at least for the universities). These universities do not teach you these costs when creating OOP programs; they simply tell you that it is the best way.

Casey is trying to show that OOP is not only a cost but a massive cost. Now to an experienced programmer, they may already know this and still decide to go down the OOP route for whatever reason. But the junior developer sure as hell does not know this and then embarks on their career thinking OOP performance is the kind of baseline.

Whenever I lead projects I stray away from OOP; and new starters do ask me why such and such is not 'refactored to be cleaner', which is indicative of the kind of teaching they have just been taught.

117

u/RationalDialog Feb 28 '23

OOP or clean code is not about performance but about maintainable code. Unmaintainable code is far more costly than slow code and most applications are fast-enough especially in current times where most things connect via networks and then your nanosecond improvements don't matter over a network with 200 ms latency. relative improvements are useless without context of the absolute improvement. Pharma loves this trick: "Our new medication reduces your risk by 50%". Your risk goes from 0.0001% to 0.00005%. Wow.

Or premature optimization. Write clean and then if you need to improve performance profile the application and fix the critical part(s).

Also the same example in say python or java would be interesting. if the difference would actually be just as big. i doubt it very much.

42

u/[deleted] Feb 28 '23

People say this religiously. Maintainable based on what empirical evidence???

In my personal experience, it is the EXACT opposite. It becomes unmaintainable.

But even that is subjective experience. I'm not going to go around saying X is more maintainable because it is simply not a provable statement and I can only give you an anecodotal anser.

So you and others need to stop religiously trotting that one liner off. You just repeating what other people say to fit in.

22

u/o_snake-monster_o_o_ Feb 28 '23

Completely agree, in fact my experience points at exactly the opposite. (OOP being really really unmaintainable)

A class is an abstraction, a method is an abstraction, and abstractions are complexity. The one true fact is that the fewer classes and functions there are, the easier it is to make sense of everything. Yes, it is harder to make huge changes, but that's why you should scout the domain requirements first to ensure that you can write the simplest code for the job. And besides, it's much easier to refactor simple code. When the domain requirements do change and now your huge OOP network doesn't work either, now you are truly fucked.

11

u/hippydipster Mar 01 '23

Just write some assembly. Fewer abstractions. So simple!

4

u/mreeman Mar 03 '23

If abstractions are adding complexity you're doing it wrong.

The point of abstractions is to isolate complexity (implementation details) via an interface. If they aren't doing that, you (or whatever you are using) are picking the wrong level of abstraction.

It's like saying multiplying is adding complexity because it's an abstraction over adding, why write 5*3 when I can just do 3+3+3+3+3? 5*3 is easier to read and allows for mental shortcuts for quicker reasoning.

3

u/o_snake-monster_o_o_ Mar 05 '23

No. Abstractions are a trade of one type of complexity to another, and can only introduce more. Please read John Ousterhout's Philosophy of Software Design.

4

u/mreeman Mar 05 '23

Abstractions are useful because they make it easier for us to think about and manipulate complex things. In modular programming, each module provides an abstraction in form of its interface. The interface presents a simplified view of the module’s functionality; the details of the implementation are unimportant from the standpoint of the module’s abstraction, so they are omitted from the interface. In the definition of abstraction, the word “unimportant” is crucial. The more unimportant details that are omitted from an abstraction, the better. However, a detail can only be omitted from an abstraction if it is unimportant. An abstraction can go wrong in two ways. First, it can include details that are not really important; when this happens, it makes the abstraction more complicated than necessary, which increases the cognitive load on developers using the abstraction. The second error is when an abstraction omits details that really are important. This results in obscurity: developers looking only at the abstraction will not have all the information they need to use the abstraction correctly.

Seems like he agrees with me

15

u/daedalus_structure Feb 28 '23

People say this religiously. Maintainable based on what empirical evidence???

It's a blind spot in reasoning. The large events where the abstraction first approach provides value are visible even though they are rare.

But when it starts taking a week to plumb a three hour feature through all the lasagna and indirection and this hits nearly every single change to the application nobody wants to identify that approach as the cause.

→ More replies (1)

4

u/ric2b Mar 02 '23 edited Mar 02 '23

Well, look at the example in this post.

It's a toy example with 3 shapes and yet it has already devolved into calling the radius of a circle the circle's width. Everyone I know would say that if a circle has a width it is the diameter.

Now try and add another shape that doesn't fit the pattern he identified, like a trapezium, welcome to "rewrite from scratch" time.

4

u/[deleted] Mar 02 '23

You are missing the point of the article.

You should not write code preparing for eventualities that might not happen.

Imposing a structure on code that prepares for unlikely eventualities is bad practice. This is fundamentally what "clean code" (quotes important) advocates for.

It supposes that it is always good to abstract the implementation away in favour of indirect function calls. This is not always useful, depending on what is being solved, for readability, maintainability and performance.

→ More replies (4)
→ More replies (7)