"Clean" Code, Horrible Performance (2023)

computerenhance.com

101 points by FrojoS 11 hours ago


taybin - 5 hours ago

Yes, a toy problem only needs a simple implementation. This is a straw man. And I don't even like Robert Martin's Clean Code, but the author is not addressing where this style actually provides benefits. When you're updating 23 if-statements because you had to add support for some new business workflow, you'll wish you had a conceptual entity that encapsulated the operations on the type of workflows so you just had to implement them in one place.

Aurornis - 5 hours ago

I consider Clean Code to be in the category of books/styles that is helpful for early developers who need some structure, but harmful to late-stage developers who adopt it as dogma.

On a long enough career path, eventually you will run into one Clean Code zealot who carries an air of superiority and nit picks every PR over things like a function having more than an arbitrary number of lines in it instead of reviewing the actual code. This is the point where most people come to hate Clean Code.

jayd16 - 5 hours ago

Ok now add a Path shape that has to calculate the area of a polygon with arbitrary complexity.

Consider how the workload is now dominated by the core task of actually calculating the area, reducing the impact of struct usage.

Consider the diffs required to make this change.

It's not like Clean Code should be taken as gospel but this micro-benchmark is not a realistic example of what CC is trying to solve.

aw1621107 - 6 hours ago

Related:

HN post for original article on 2023-02-28 (https://news.ycombinator.com/item?id=34966137), 739 points, 914 comments

Discussion between Casey (author of this article) and Uncle Bob (author of _Clean Code_, whose programming patterns Casey is critiquing), posted on HN on 2023-03-11 (https://news.ycombinator.com/item?id=35105528), 223 points, 213 comments

"Horrible Code, Clean Performance", a "homage" to Casey's original article, posted on HN on 2023-04-19 (https://news.ycombinator.com/item?id=35596069), 121 points, 114 comments

jeffnash - 2 hours ago

It seems like the main takeaway is that many textbook OO paradigms aren't the most optimized representations of the code. In this case, the cost is dynamic dispatch and pointer-chasing. This is a function of the Shape abstraction, but not the abstraction itself.

But the argument is you're trading some of that performance optimization for maintainability. None of this is exactly news. And while I'm here ranting: I never understood why shapes are the canonical OOP example. Shapes are a closed set of types (yes I'm sure GPT-324 invented a new one) with an open set of operations. There's always going to be one more thing you need to do with those shapes, but you'll never be adding new shapes down the road unless you are still in Kindergarten. OOP is useful for the exact opposite case, where there is a relatively fixed set of operations and you routinely introduce a new subtype that needs to perform all or most of those operations.

I've noticed that most courses that introduce the concept of OOP do so in a way that (perhaps unintentionally) emphasizes the false notion that everything should have an 'x-is-a-y' taxonomy before actually asking the question if that is appropriate. Putting the Cart extends Vehicle before the Horse extends Animal.

cratermoon - 6 minutes ago

This is Muratori showing he's a solo programmer who has only ever worked on relative small, simple software that runs on a single machine.

teddyh - 14 minutes ago

Please note that this criticism is from 2023, but the “Clean Code” book has a second edition from 2025, extensively revised to account for the many misconceptions which new programmers might have gotten from the old edition, such as interpreting rules too strictly, etc.

scelerat - 4 hours ago

How much of the performance differences come down to language or compiler choice in these examples?

Would I see the same kinds of performance gains or losses avoiding or using certain patterns in Go or Rust or Java? Are they the same examples as in C++?

What about dynamic languages like ruby or python or javascript?

narnarpapadaddy - 3 hours ago

I think performance generally trades along a different axis: open-world vs closed-world assumptions. There are many cases where closed-world assumptions may confer performance benefits, such as tree-shaking, whole program optimization, and using switch statements rather than a class hierarchy. Whereas designing for extensibility necessarily precludes some of those choices (though it doesn’t necessarily require OOP, for example registering a handler in a table). In other words, it’s easier to optimize a problem that is fixed and well-understood, versus one flexible and unknown. Take that ideas to the extreme and end up at ASIC bitcoin miners.

usr_222 - 3 hours ago

The only reason why your code is slow or bad - because you created it in such a way, not due Clean Code.

I cannot stop being surprised by how ridiculously short-sighted developers are - and how you continue to believe in golden hammers and silver bullets. You want to build a car, so you take the “Clean Code” hammer and try to build one with it. Then you say, “Hmm, I built a car using the Clean Code hammer, but it cannot even reach 100 km/h. Therefore, Clean Code is bullshit.”

This is ridiculous.

The same applies to blind followers of Clean Code and SOLID who build systems without any high-level understanding of the system they are trying to create. The result is almost always an unreadable, unmaintainable pile of shit. In fact, they are all in the same boat.

All of these principles are just that: principles. They are not specifications to be implemented. Moreover, they are LOW-LEVEL principles. So, they cannot be “bad,” “good,” “slow,” or “fast”. Your code is bad or slow - not the programming principles.

Until you understand what you are trying to build and how it should work, you cannot decide whether Clean Code, SOLID, GoF patterns, or any other principles are appropriate. Once you have a solid architectural backbone that satisfies the required system characteristics, you can apply the principles that help you implement that design in the simplest and most effective way.

And each principle has its own trade-off with other principles! --- too much DRY -> dead coupling (all these “cores” and “libraries” that team leads cobble together at night and proudly turning a distributed system into monolith) --- too loose coupling -> excessive fragmentation -> low cohesion and broken incapsulation --- excessive SRP -> low cohesion and so on and so on.

So it is not Clean Code bad - you just not understand what Clean Code and other principles are.

glitchc - 4 hours ago

I'm not sure I follow the thrust of the article. The author starts off with talking about clean code, but then compares OO with procedural code. It's not the same thing, and of course we've always known that OO abstractions carry a performance penalty. Even the founders of OO (Alan Kay et al.) acknowledged the memory and compute impact, but thought it was a worthwhile tradeoff for clean abstractions in complex code-bases.

Back then computers were far less performant than they are today, so the first languages (e.g. SmallTalk) had to be compiled into a bytecode VM that ran on a Xerox PARC. Other efforts included hardcoding some of the constructs into the ISA.

flossly - 6 hours ago

I'd say Clean Code is teaching many bad-practices. Too many to be recommended.

wduquette - 4 hours ago

Make it work, then make it "clean" (that is, readable and maintainable); then make it fast, and only if measurement indicates that it matters.

meerita - 5 hours ago

"Code Complete" by Steve McConnell is a good option for those who want to improve their development practices.

bluGill - 5 hours ago

I stopped reading as soon as I saw the shape class. This example (along with the proverbial animal) has done a lot of harm to OOP and programming. You need base classes (which are not always the right answer, but when they are) to be based on the abstract concept you need to model not something real that is easy to understand when someone isn't an expert in your domain.

devmor - 4 hours ago

Performance vs. Maintainability is the infinite debate, and it’s a mind numbing one because in the vast majority of professional roles you will have the opportunity to prefer neither.

MonstraG - 11 hours ago

(2023)

ErroneousBosh - an hour ago

This is just bloody stupid.

If you care about performance, you don't use OOP, you don't use if/else, you don't use switch{case}, what you do is you write the hot parts in assembler.

If you aren't writing it in assembler, you're writing slow code.

But that code is still not optimised until you've implemented it in an ASIC.

jgwil2 - 6 hours ago

See also the more in-depth followup "Simple Code, High Performance (https://www.youtube.com/watch?v=Ge3aKEmZcqY)

- 6 hours ago
[deleted]