Live data from Hacker News

“Clean” code, horrible performance

computerenhance.com

861–870 of 932 posts

Re: “Clean” code, horrible performance

#861
post #651
post #585

Earlier quoted context omitted.

What happens if library user wants to extend functionality? They can't inject their code into the library.

Yeah, it's very awkward. Your best option is to leave a 'hole' case where someone may provide a 'data type' set of functions satisfying an interface, and the library author simply calls them. Effectively you're adding an OO escape clause, but it's ugly and will break user code when you add more functions and grow the interface. Conversely, in a codebase organized by objects it's not clean to add an extra method to th…

Bob Nystrom has a good article on this (the expression problems it’s called)

https://journal.stuffwithstuff.com/2010/10/01/solving-the-ex...

He also discusses it in his book Crafting Interpreters.

Re: “Clean” code, horrible performance

#862
post #517

Earlier quoted context omitted.

I'd actually say this article is generally unhelpful - it's good to be aware but as someone who works on sorting out performance critical things I want the code to be as clean as humanly possible going in. Whether you write clean or dirty code if you're a junior developer you're probably not going to write performant code and even senior devs may be able to sniff what might be a bottleneck in advance but most of us h…

Maintainability and cleanliness are not the best virtues code can have. Far more important are that it work correctly and quickly.

I agree that correctness is pretty essential (as in - actually does what it says, though something that's mostly correct is almost always the bar... most software doesn't need to be entirely correct). But I am confused about "quickly" do you mean dev time or execution time?

Re: “Clean” code, horrible performance

#863
post #263
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…

100%, I’ve done tonnes of (backend) performance optimization, profiling, etc. on higher level applications, and the perf bottlenecks have never been any of the things discussed in this article. It’s normally things like: - Slow DB queries - Lack of concurrency/parallelism - Lack of caching/memoization for some expensive thing that could be cached - Excessive serialization/deserialization (things like ORMs that create…

One I found with profiling--when writing the code n was quite small. Many database operations simply iterated over an array to decide where to store an item. The time spent dealing with the data was a tiny fraction of the database round trip time, there simply was no reason to get fancy.

Over the years they've grown and one bin showed up where jobs would sit around for weeks--for that case n went from rarely having a screenful of lines to a few thousand--oops, now more than 2/3 of the time was spent in those searches. (And I have a sneaking suspicion that a good portion of the remaining time comes from using field names to retrieve values. The profiler doesn't separate that out, though, because it's not my code.)

Re: “Clean” code, horrible performance

#864
post #799

Earlier quoted context omitted.

A 20x performance improvement is not a "small" efficiency.

A 10000x performance gain could still be insignificant, see Amdahl's law. That's why you need to understand bottlenecks in your system before going around and start optimizing things, as it could be pointless or even counter productive.

No, I don't actually agree with this at all. Sometimes -- a lot of the time actually -- you can have a pretty good idea ahead of time what will be fast and what will be slow. If you design the system before thinking about this, you can paint yourself into a corner and lock-in a fundamentally slow architecture, just like you can lock yourself into a fundamentally un-maintainable architecture.

Like, when you're choosing a big data structure that is going to have lots of by-value lookups, you don't implement it as an array with O(n) lookup first and only move to a hashtable after benchmarking it. That would be absurd. You just use a hashtable with O(1) lookup right at the start. Because in the overwhelming majority of cases that's the right thing to do and it doesn't need any justification. And the reason you can do that is because you're an engineer and you know a damned thing about the domain you're working in.

Structural engineers don't build a skyscraper out of paper mache first, and then rebuild it in concrete when it collapses in a stiff breeze. They just build it out of concrete the first time around.

What so many people thoughtlessly call "premature optimization" isn't "premature" at all, it's just "knowing about the problem and knowing how the computer works". When you deliberately ignore this, what you're actually doing is "premature pessimization". Coding as if you don't know the difference between cache and RAM in 2023 is like coding as if you don't know the difference between RAM and disk in 1973. It's negligence. You know better!

And look at what the Clean Code people want you to do instead. All these rules are geared towards future extensibility. Is that not a form of premature optimization? But optimizing for extensibility, not speed. And you end up with codebases littered with abstract interfaces that only have (and will only ever have) one implementation. But you pay for that premature abstraction in both cognitive load and CPU load. You ain't gonna need it!

Re: “Clean” code, horrible performance

#865

Earlier quoted context omitted.

Casey makes the point that you don't have to hand-tune assembly code, but instead just write the simpler code . It's easier to write, easier to read, and runs faster too! If there's something wrong with that advice, I can't imagine what it is...

"Easier to write, easier to read" is the part that's wrong with that advice. It absolutely is, on toy problems like the one described in the article. It very frequently is not when embedded in much larger domains as part of large projects maintained over years by teams.

This. Clean code isn't about writing stuff like this. For what he's talking about the overhead of polymorphism is a major part of the total cost and his case is simple enough that there's little value.

However, the bigger your task gets the more value there is to polymorphism and in general the smaller the percent of total time goes to the polymorphism overhead.

And note that his attack is only on polymorphism, not the other aspects of clean code. I strongly suspect the compiler optimizes away much of the clean stuff I do but I have never checked. I also find profiling easier on cleaner code, it makes it very obvious where the time sink must be and thus what warrants expending effort to improve. Profiling almost always shows the vast majority of time going into the unavoidable (say, disk reads) and a small number of other routines. Spend your optimization effort on the spots that need it because 99+% of your code doesn't run often enough for it to matter.

Re: “Clean” code, horrible performance

#866

Earlier quoted context omitted.

Casey Muratori knows a lot about optimizing performance in game engines. He then assumes that all other software must be slow because of the exact same problems. I think the core problem here is that he assumes that everything is inside a tight loop, because in a game engine that's rendering 60+ times a second (and probably running physics etc at a higher rate than that) that's almost always true. Also the fact that…

This comment helped make sense of this whole comment section for me. I work in game development, largely with optimisation. I mostly work with GPU optimisation, which is a whole different beast. On the CPU, most of the time issues are either trying to do too much stuff in a hot loop (rendering stuff that could have been culled, putting physics on objects that don't need it,...) or doing something in a slightly ineffi…

Hot loops are where you spend your optimizing efforts. If you're going through that list of shapes again and again it very well might be worthwhile to cache some data and provide the objects with a way to update the cache.

Re: “Clean” code, horrible performance

#867
Sometimes I see very good programmers writing functions that IMO are much much too long and have far too much internal state for one function. I believe there might be a correlation between these people having C++ backgrounds. Other than that I'm just mentioning it as an observation.

Re: “Clean” code, horrible performance

#868
post #787
post #367

Earlier quoted context omitted.

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.

How is it a strawman when it's literally taken from a Clean Code textbook?

His benchmarks aren't taken from the textbook. If you benchmarked the textbook's changes in a realistic context you'd get quite different results.

Re: “Clean” code, horrible performance

#869

Earlier quoted context omitted.

No; I have no idea why its so slow. Its kind of hard to tell - I guess I could use wireshark to trace the packets. But who cares? At least one of these things is true: - It makes horribly inefficient use of my CPU - It needs an obscene number of network round-trips to load - One of the network servers that discord needs to open takes seconds to respond to requests This isn't a new problem. Discord always takes about…

> The only reason most software runs slowly is because the developers involved don't care enough to make it run fast. There is truth to that, but also: * some of them would care if they knew what was possible with reasonnable effort (that's what Casey is trying to address. So far in the course i'm not really seing much that I could apply to the kind of code I write, sadly - but I'm hoping to learn stuff.) * it's very…

Right; most teams optimize for velocity before performance.

This makes sense when you're a shiny new startup. But seriously, 10 seconds for discord to open? There's a point in every product's lifecycle where performance is a feature. Discord isn't a startup anymore. Why can't they fix these performance problems? At least discord is pretty snappy once its loaded. The new reddit interface? Its a hog. But despite a massive outcry, why haven't they fixed it?

My pet theory is that they don't know how. And talking about velocity is just a smoke screen.

I think most professional engineers don't really understand the software stack well enough to be able to improve the performance of the software they write. Its pretty understandable - nobody asks about this stuff in job interviews. And the software stack only gets more complicated each year. If you follow React tutorials online, you can get pretty far adding features to a web app without ever needing to understand how react actually works. Or the web browser, and Vite / webpack / whatever and the operating system it runs on top of.

And thats a pretty good deal! More engineers! So long as we don't mind the new reddit site. And electron apps that take seconds to load.

Of course Casey Muratori knows how to write performant code. He understands the whole stack. He knows how to read the assembly that the C++ compiler produces. Thats something more of us should aspire towards.

I wonder if it would be valuable to make an online course talking about performance engineering. I feel like its one of those things that has fallen by the wayside, and I think thats a massive pity.

Re: “Clean” code, horrible performance

#870
post #172

There's a tradeoff. Engineering time is expensive. Machine time can be expensive too. We need to optimize these costs by making most code that's not performance relevant easy to read and then optimize performance critical code paths while hiding optimization complexity behind abstractions. Either extreme is not helpful as a blanket method.

User time is expensive too.

Depending on who is making the purchasing decision this (sadly) might not be relevant. Looking at you, SAP.
Post reply on HN