Live data from Hacker News

“Clean” code, horrible performance

computerenhance.com

361–370 of 932 posts

Re: “Clean” code, horrible performance

#361
post #292

Earlier quoted context omitted.

Have you measured CPU time? A very large factor will be Disk IO and Network

Exactly. The webpage is probably asking for resource from 10 different servers and one of them is a bit slower than the others, and the page rendering itself likely doesn't take very long.

Which is precisely the point made couple comments up. Calling a lot of virtual methods in the critical path is peanuts compared to making a lot of network requests in said critical path.

But hey, those network calls are fast on my loopback interface, or my company LAN, when I'm playing with the dev version, using test set simulating 2 users and 5 posts for each. Surely it'll be just as fast for the real users, over the Internet, on channels with 1000 users and 5 posts per second.

Re: “Clean” code, horrible performance

#362

Earlier quoted context omitted.

Since you bring up React in your example, which framework should one use to build better performing web apps? I know React tends to lack in both dev UX and performance (at least in my exp). Personally I've taken a look at Svelte and Solid, and liked them both. I haven't had the chance to build anything larger than a toy app, though.

Vue could also be an option, but I personally want to learn some Solid, as I see it could be preferred by the current mass of React frontend developers, more than Svelte and Vue. The syntax and philosophy of Solid looks closer to React, while having a stronger focus on performance.

Okay, I'll bite: does Vue perform better than React? Your post makes no mention of this, I don't know if it does, and offering it as an alternative due to performance reasons, without knowing this, seems a tad premature.

Re: “Clean” code, horrible performance

#363
Maintainable code or performant code, yes. That's always a tradeoff. The most high performance code will be manually tuned assembly, but I don't see author writing in assembly, so he's already made some tradeoff against performance. It's all down to your priorities.

Re: “Clean” code, horrible performance

#364
This thread is, predictably, another demonstration of conflating optimisation with being aware of performance.

The presented transformation of code away from “clean” code had nothing to do with optimisation. In fact, it made the code more readable IMO. Then it demonstrated that most of those “clean” code commandments are detrimental to performance. So obviously when people saw the word “performance”, they immediately jumped “omg, you’re optimising, stop immediately!”

Another irritating reaction here is the straw man of optimising every last instruction: the course so far has been about demonstrating how much performance there even is on the table with reasonable code, to build up an intuition about what orders of magnitude are even possible. Casey repeated several times that what level of performance is right for your situation will depend on you and your situation. But you should be aware of what’s possible, about the multipliers you get from all those decisions.

And of course people bring up profilers: no profiler will tell you whether a function is optimal or not — only what portion of runtime is spent where. And if all your life you’ve been programming in Python, then your intuition about performance often is on the level of “well I guess in C it could be 5-10 times faster; I’ll focus on something else”, which always comes up in response to complaints about Python. Not even close.

Re: “Clean” code, horrible performance

#365
Maintainability and performance are often at odds, but that doesn't mean you should throw out one for the other in every case, and I don't think that's what people like Robert C. Martin were ever intending with Clean Code.

It's like database denormalization, it may violate normalization principals but it when applied to a well designed database is a valid optimization technique when done with proper understanding of the implications of said optimizations.

More importantly though, we are willing to sacrifice raw performance for developer experience and higher maintainability because developer time is expensive, and most stakeholders would prefer that you can add feature xyz in a reasonable time, over feature xyz running marginally faster. If ease of development and maintenance weren't important, we'd just write everything in assembly and bypass all these abstractions altogether.

Re: “Clean” code, horrible performance

#366

Earlier quoted context omitted.

It doesn't. TDD is about writing new code. It doesn't say anything about existing tests being sacrosanct, or pinning tests sticking around forever. I can extract code from a function and write tests for it. I probably know that there's still code that checks for user names but I can't guarantee that this code is being called from function X anymore, or whether it's before or after calling function Y. Those are the so…

> TDD is about writing new code. TDD is about documenting behaviour. Which is why it was later given the name Behaviour Driven Development (BDD), to dispel the myths that it is about testing. It is true that you need to document behaviour before writing code, else how would you know what to write? Even outside of TDD you need to document the behaviour some way before you can know what needs to be written. A function'…

> A function's behaviour should have no reason to change after its behaviour is documented.

That's only true with spherical cows. That something happens is a requirement. When it happens is often only as specific as 'before' or 'after' but tests often dictate that they happen 'between', which is not an actual requirement, it's an accident of implementation. It was 'easy' to put it here.

Nowhere is it written that behavior in a system is strictly additive.

Systems are full of XY problems. When you recognize that, and start addressing that problem, you sprout a lot of tests for the Y solution and block delete tests for the X solution. That behavior doesn't exist in the system anymore because it's answering the wrong question. Functional parity tests can be copied, or written in parallel. But the old tests disappear with the old code (when the feature toggle goes away).

Leaving the code for X around is at best a footgun for new devs, and at worse a sign of hoarding behavior of an intensity that requires therapy.

You're espousing a process whereby you've nailed one foot to the deck, preferring form over function. Whether you believe what you're saying or not I can't say, but it's restrictive and harmful.

Re: “Clean” code, horrible performance

#367
post #15

This guy is so dogmatic about it it hurts. I would argue that clean code is a spectrum from how flexible vs how rigid you want your abstractions to be. If your abstractions are too flexible for good performance, dial them back when you see the issue. If your abstractions are too rigid for your software to be extendable, then introduce indirection. We can all write code that glues a very fixed set of things end to end…

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.

These examples are absolutely a strawman. He's imagining there's one specific access pattern that's executed thousands of times per second. In a realistic codebase you're accessing the data less often but in multiple different (often subtly so!) ways. Cache efficiency is everything for modern CPUs, so you can't "simplify" the access patterns without making your benchmarks unrepresentative.

Re: “Clean” code, horrible performance

#368
post #179

I think the author is taking general advice and applying it to a niche situation. > So by violating the first rule of clean code — which is one of its central tenants — we are able to drop from 35 cycles per shape to 24 cycles per shape Look, most modern software is spending 99.9% of the time waiting for user input, and 0.1% of the time actually calculating something. If you're writing a AAA video game, or high perfo…

What does it matter if it does this 0.1% ten times slower than it could? Then user will have to wait for the software which slows the most expensive component of the whole work setup, the human.

if the software ever takes more than 10ms to do something it is stealing time from the human. the human is the slowest part of the system so nothing else should ever make the slowest part even slower.

Re: “Clean” code, horrible performance

#369

Earlier quoted context omitted.

> No one is working with a huge amount of data in big loops using virtual methods to take every element out of a huge dataset like he is showing. Things way worse than that exist. Replace "virtual method" with "service call."

"Don't make tons of RPCs" is a totally separate issue from "don't make subclasses because virtual methods cost a few extra cycles".

It's the same problem. Virtual calls are degenerate, in-process RPCs. Or put another way, the reason you make tons of RPCs is the same reason you make tons of virtual calls: you consider services or subclasses to be cheap, so you use them a lot to mold your systems to organizational/people problems instead of the thing the software is supposed to do.

Re: “Clean” code, horrible performance

#370

Earlier quoted context omitted.

> Look, most modern software is spending 99.9% of the time waiting for user input, and 0.1% of the time actually calculating something. If you're writing a AAA video game, or high performance calculation software then sure, go crazy, get those improvements. That's really not even close to true. Loading random websites frequently costs multiple seconds worth of local processing time, and indeed, that's often because o…

> That's really not even close to true. Loading random websites frequently costs multiple seconds worth of (...) You attempted to present an argument that's a textbook example of an hyperbolic fallacy. There are worlds of difference between "this code does not sit in a hot path" and "let's spend multiple seconds of local processing time". This blend of specious reasoning is the reason why the first rule of software o…

The subfields of programming I know the most about are game development, networking, and web development, and in all of those, it's not the case that only 1% of the code is in the "edge case" where performance matters at all.

For example, in the case of web development, if you build a medium-sized website with React (i.e. pretty normal behavior nowadays), then if you make default decisions that don't consider performance at all, your website will end up noticeably slow, because you will:

1. Write code that re-renders components all the time during loading and UI interactions,

2. Which depend on tons of third-party dependencies that perform poorly,

3. So you end up spending a ton of time in re-renders while the site loads and while someone is using it.

Dealing with this isn't literally the same performance work that Casey put in his article, because it's at a slightly higher level of abstraction, but it requires the same mindset. It requires writing most of your code (and taking on dependencies) with performance in mind, not just 1% of it. You can't avoid it without your notion of "clean code" including some amount of mechanical sympathy, rather than just being about abstract extensibility and generalization concerns.

Post reply on HN