Live data from Hacker News

"Clean" Code, Horrible Performance (2023)

computerenhance.com

81–90 of 192 posts

Re: "Clean" Code, Horrible Performance (2023)

#81
post #19

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 t…

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

Why have you drawn the conclusion that the author is against this? A function with a switch-statement can do this.

Re: "Clean" Code, Horrible Performance (2023)

#82
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.

Re: "Clean" Code, Horrible Performance (2023)

#83

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 nev…

> In this case, the cost is dynamic dispatch and pointer-chasing.

To sharpen your statement, the cost is missing the CPU caches, which is often caused by failing to pool allocations and reading indirectly.

> But the argument is you're trading some of that performance optimization for maintainability.

Right, but exactly how much? I would argue "very OOP" design styles neuter your ability to optimize the system, and sometimes necessitate that you are kept at arms-length from the system, only capable of "customizing" it via more abstract API layers. I do believe certain OOP practices can make maintaining software easier, but I also believe we have not figured out how to retain control over the computer in the face of these abstractions.

As an example, Clean Coders advocate for "separation of responsibilities" and often speak in terms like "ownership" or what a function/class "knows about" or "should have to know about." When different classes are given different data-fields in the pursuit of making it clearer (what should exist in that scope,) you are creating a constraint which is virally spread through the codebase which runs counter to what the CPU wants. The CPU wants an array, but you can't have an array because the FileManagerFile can't "know about" the FileManagerFileCache, and the FileManagerFileCache can't known about the FileCache, so now each FileManager "owns" its own cache, which is an entirely separate heap allocation.

Re: "Clean" Code, Horrible Performance (2023)

#84
post #19

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 t…

> 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. Why have you drawn the conclusion that the author is against this? A function with a switch-statement can do this.

switch is example of explicit control flow, which Clean Code argues strictly against.

the better approach would be to use implicit control flow using class hierarchies, interfaces, and such and rely on class behavior, polymorphism and runtime dispatch, instead of explicit switch() which tends to multiply itself across the codebase

Re: "Clean" Code, Horrible Performance (2023)

#85

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?

I believe in Rust there would be almost no performance hit due to the compiler using monomorphizing everything via the "zero-cost abstraction" we love to brag about

Re: "Clean" Code, Horrible Performance (2023)

#86

Earlier quoted context omitted.

> 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. Why have you drawn the conclusion that the author is against this? A function with a switch-statement can do this.

switch is example of explicit control flow, which Clean Code argues strictly against. the better approach would be to use implicit control flow using class hierarchies, interfaces, and such and rely on class behavior, polymorphism and runtime dispatch, instead of explicit switch() which tends to multiply itself across the codebase

You accidentally used the phrase better approach, instead of Clean Code.

Re: "Clean" Code, Horrible Performance (2023)

#87
post #19

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 t…

Indeed. The problem is trying to apply the principles of "Clean Code" or more generally of OOP everywhere. There are surely cases where having an interface as an abstraction and multiple implementations makes sense. There are case where it doesn't, and if you take as a dogma "everything shall be the implementation of an interface" you get more complex code and performance penalty for nothing. There is nothing wrong w…

> There are surely cases where having an interface as an abstraction and multiple implementations makes sense.

I think most people aren't aware of the alternative, which is: A function that can call different implementations based on some other variable.

E.g. instead of having RealDB and MockDB type have a createUser() (method), you have a createUser() (function) that switches part of it's logic based on what DB is selected.

That's the prodecural way of achieving the same thing without needing a concept for virtual functions.

Casey explains this in the long discussion with Uncle Bob.

Re: "Clean" Code, Horrible Performance (2023)

#88

Earlier quoted context omitted.

Indeed. The problem is trying to apply the principles of "Clean Code" or more generally of OOP everywhere. There are surely cases where having an interface as an abstraction and multiple implementations makes sense. There are case where it doesn't, and if you take as a dogma "everything shall be the implementation of an interface" you get more complex code and performance penalty for nothing. There is nothing wrong w…

> There are surely cases where having an interface as an abstraction and multiple implementations makes sense. I think most people aren't aware of the alternative, which is: A function that can call different implementations based on some other variable. E.g. instead of having RealDB and MockDB type have a createUser() (method), you have a createUser() (function) that switches part of it's logic based on what DB is s…

Are you suggesting something like this?

    def createUesr(db):
        if db is type1:
            behaviour1
        if db is type2:
            behaviour2

Re: "Clean" Code, Horrible Performance (2023)

#89
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.

Re: "Clean" Code, Horrible Performance (2023)

#90
post #46

Earlier quoted context omitted.

Indeed. The problem is trying to apply the principles of "Clean Code" or more generally of OOP everywhere. There are surely cases where having an interface as an abstraction and multiple implementations makes sense. There are case where it doesn't, and if you take as a dogma "everything shall be the implementation of an interface" you get more complex code and performance penalty for nothing. There is nothing wrong w…

The principle of clean code includes KISS, therefore complex code for nothing isn't clean code

Sure, but then Clean Code goes and directly pushes for polymorphism in an area (branching) where indirection and polymorphism is known to be costly for both complexity and performance.

An aspect of this that I wish Muratori had touched on when he wrote this in 2023 is how each of these tenants he has issues with in Clean Code are just trading complexity. All four of the structural rules that Muratori demonstrated issues with generally don't reduce complexity. At best, each trades one type of complexity for another.

There are some great ideas in Clean Code, but outside of DRY, the structural recommendations tend to be more harmful than good.

Post reply on HN