Live data from Hacker News

“Clean” code, horrible performance

computerenhance.com

131–140 of 932 posts

Re: “Clean” code, horrible performance

#131
post #91

Earlier quoted context omitted.

Casey is a bit of a hardcore crusader on the topic, but I'd hardly call dogmatic someone who can provide you evidence and measurements backing their thesis. The tests he put together here are hardly something I'd call a straw-man argument, they seem like reasonable simplification of real-cases.

Evidence in a micro benchmark of a single page of code. The focus on performance here ignores the fact that most programs are large systems of many things that interact with each other. That is where good design and abstractions and “clean code” can really help. Like all things it is about finding a balance and applying the right techniques to the right parts of a larger system.

I'd say that it really depends on what the code needs to do.

For example, if the code is to be distributed and extended as a third-party library, then the class hierarchy is probably a better fit to allow extensibility.

But if the purpose of the API is to compute the area of given shapes (as in the example), then it makes sense to make it efficient and there is no use to provide extensibility to the outside world.

The advocates of "clean code" that Casey mentions will go for extensibility no matter the use.

I find it very interesting to have numbers to weight what you are leaving when you go the extensibility route instead of the non-pessimistic route.

Re: “Clean” code, horrible performance

#132
post #7

Earlier quoted context omitted.

It doesn't just make devs easier to replace. It makes it my job more pleasant (and that of my colleagues). But yes, you're right. It does also help onboard people. Imagine working as a barista with a disorganised bar, a mat on the floor that keeps sliding and a corner is sticking up, and one bag of beans where half the side is decaf and the other is normal. Now compare that to working in a more common sense coffee sh…

It seems like you may be assuming that Casey is arguing against writing clear code, which he is not. He is arguing that you should just write the simple thing and usually that is also the most clear, readable and "maintainable" code because it is easy to get an overview of. So what he is arguing for does not fit your coffee shop example, because of course no one should write unreadable code. The argument is that some…

This advice doesn’t really differ from the actual ‘source material’ though. It’s really arguing against the people that learned what “clean code” is from a blog post or a Tweet or (most likely of all) another YouTuber that tried to take a complex engineering topic that they don’t have the experience to understand, and shove it into a video-listicle full of DigitalOcean ads and forced facial expressions.

You see the same thing with microservices. Any of the reading material by the big / original proponents of microservices is actually quite good at giving you all the reasons why they probably aren’t for you. But that doesn’t stop the game of telephone that intercepts the message before it gets do most developers.

So I really just see this whole thing as someone saying “RTFM”, rather than it being any sort of derived nuanced take.

The sooner a professional software developer can get themselves off the treadmill of garbage trendy educational content, the better.

Re: “Clean” code, horrible performance

#133
post #108

Earlier quoted context omitted.

In this particular case I find the code optimized for speed (the one using switch) to be also more readable and simpler than the code using virtual dispatch. The problem with virtual calls in a big project is that there is no good way of knowing what is the target of the call, without some additional tooling like IDE. But in case of a switch/if, it is pretty obvious what the cases are.

Sure, but what happens, once you want to start supporting other shapes other than basics? Because clean code assumes code will be changed/maintained. Then you get people writing their own horrible hacks. Both clean code and performance oriented design have their extremes. Clean Code has Spring with Proxy/Method/Factory monster... and hyper performance has the extreme in the story of Mel (i.e. read-and-weep only code)…

> Sure, but what happens, once you want to start supporting other shapes other than basics? Because clean code assumes code will be changed/maintained.

You get to push back and ask, is it worth the developer time and predicted 1.5 - 5x perf drop across the board (depending on shape specifics)? In some cases, it might not be. In others, it might. But you get to ask the question. And more importantly, whatever the outcome, you're still left with software that's an order of magnitude faster than the "clean code" one.

Clean code "assumes code will be changed/maintained" in a maximally generic, unconstrained way. In a sense, it's the embodiment of "YAGNI" violation: it tries to make any possible change equally easy. At a huge cost to performance, and often readability. More performant code, written with the approach like Casey demonstrated, also assumes code will be changed/maintained - but constraints the directions of changes that are easy.

In the example from video, as long as you can fit your new shape to the same math as the other ones, the change is trivial and free. A more complex shape may force you to tweak the equation, taking little more time and incurring a performance penalty on all shapes. Even more complex shape may require you to rewrite the module, costing you a lot of time and possibly performance. But you can probably guess how likely the latter is going to be - you're not making an "abstract shape study tool", but rather a poly mesh renderer, or non-parametric CAD, or something else that's specific.

Re: “Clean” code, horrible performance

#134
post #91

Earlier quoted context omitted.

Evidence in a micro benchmark of a single page of code. The focus on performance here ignores the fact that most programs are large systems of many things that interact with each other. That is where good design and abstractions and “clean code” can really help. Like all things it is about finding a balance and applying the right techniques to the right parts of a larger system.

True, the example is simplistic, but that's just to make it fit within reasonable exposition. The author has in the past shown (elsewhere) how his techniques can actually make dramatic differences in more concrete examples (he rose to some Internet fame for building a performant shell that could actually handle larger outputs orders of magnitude better than most available alternatives). To me the interesting point is…

It was Windows Terminal he wrote something faster than. Windows terminal was doing a whole GPU draw call per character (at 2x standard terminal height, 160x25, it was as many draw calls as a AAA game).

Re: “Clean” code, horrible performance

#135
post #13

I think he's really underplaying the main selling point of clean code - the objective of writing clear maintainable, extendable code. His code was faster, but sometimes how it compares for adding new features or fixing bugs by people new to a code base is where you want to optimize. Should performance be talked about more? Yes. Does this show valuable performance benifits? Also yes. Is performance where you want to s…

If someone is new to the codebase, would you rather they need to open a dozen files to see all of the different virtual functions that could occur at one call site, or open one file?

Honestly this itself is a massive oversimplification, and a bit of a strawman, and kinda indicates that you still aren’t seeing the nuance.

Yes, if something is understandable in a single file, that’s fine. But also appreciate that too many pieces in the same file can also be confusing and disorienting for people. You also have to consider all the cases in which someone would be opening that file.

You’re basically posing a situation which by its very description is an exception. If anyone is slavishly following these rules, they’re undoubtedly doing it wrong.

Knowing when to apply the patterns is the hard bit. And, in my experience working on codebases worthy of considering these things in the first place, there’s much more to consider than what you’re posing.

Re: “Clean” code, horrible performance

#136
post #127
post #120

Earlier quoted context omitted.

One can argue that extremes of fast and clean code will both result in something horrific. What Casey is doing is showing how bad a hammer is at removing screws. I mean duh, you're removing screws with a hammer.

I don't understand what you are saying. My comment was a jest (as suggested by the smiley). What I take from Casey's post is that a simple non-pessimistic representation allows for efficient code. That is, using a table instead of a class hierarchy gives massive performance boost. Compared to a "clever" loop unrolling doesn't give that much of a boost. So we need simpler representation. IMHO the table implementation…

> a simple non-pessimistic representation

That's the insight, I think. "Clean Code" tells you to use maximally pessimistic representation for everything, because everything could be extended in some way in every direction. Meanwhile, in the real world, you likely have a good idea what directions of evolution are possible, and which of them are even useful.

Casey's example shows you that, if you design your code to make use of those assumptions, you'll get absurd performance benefits for little to none loss in readability (and perhaps even a gain!).

Some may ask, "what if you're wrong with your assumptions?". Well, you pay a price then. Worst case, you may need to rip out a module, rethink the theory behind it, and rewrite it from scratch - likely forgoing some of the performance benefits, too. Usually, the price will be much smaller. Either way, it's still better than being maximally pessimistic from the start, and writing software that never had a chance of ever becoming good or fast.

Re: “Clean” code, horrible performance

#137

I take issue with the idea that maintainable code is about "making programmers' lives easier", rather than "making code that is correct and is easy to keep correct as it evolves". Correctness matters for the user - indeed, sometimes it is a matter of life and death.

> I take issue with the idea that maintainable code is about "making programmers' lives easier" He's talking about "clean code", not maintainable code. The claim that "clean code" is more maintainable is an unproven assertion. Whenever I interact with a "clean code" codebase, it is worse in every way compared to the corresponding "non-clean" version, including in terms of correctness.

Difficult to prove. I'm no OOP evangelist, but the "clean" version in the video looks clearer to me.

Re: “Clean” code, horrible performance

#139
What is the author suggesting? To write software using infinite loops changing global state? Makes sense for video games but not for the custom enterprise software where clean code practices are usually applied.

The enterprise code must be easy to change because it deals with the external data sources and devices, integration into human processes, and constantly changing end-user needs. Clean code practices allow that, it's not about CPU performance and memory optimizations at all.

Post reply on HN