logoalt Hacker News

GuB-42today at 2:35 PM15 repliesview on HN

> Premature optimization is the root of all evil.

There are few principle of software engineering that I hate more than this one, though SOLID is close.

It is important to understand that it is from a 1974 paper, computing was very different back then, and so was the idea of optimization. Back then, optimizing meant writing assembly code and counting cycles. It is still done today in very specific applications, but today, performance is mostly about architectural choices, and it has to be given consideration right from the start. In 1974, these architectural choices weren't choices, the hardware didn't let you do it differently.

Focusing on the "critical 3%" (which imply profiling) is still good advice, but it will mostly help you fix "performance bugs", like an accidentally quadratic algorithms, stuff that is done in loop but doesn't need to be, etc... But once you have dealt with this problem, that's when you notice that you spend 90% of the time in abstractions and it is too late to change it now, so you add caching, parallelism, etc... making your code more complicated and still slower than if you thought about performance at the start.

Today, late optimization is just as bad as premature optimization, if not more so.


Replies

austin-cheneytoday at 2:44 PM

The most misunderstood statement in all of programming by a wide margin.

I really encourage people to read the Donald Knuth essay that features this sentiment. Pro tip: You can skip to the very end of the article to get to this sentiment without losing context.

Here ya go: https://dl.acm.org/doi/10.1145/356635.356640

Basically, don't spend unnecessary effort increasing performance in an unmeasured way before its necessary, except for those 10% of situations where you know in advance that crucial performance is absolutely necessary. That is the sentiment. I have seen people take this to some bizarre alternate insanity of their own creation as a law to never measure anything, typically because the given developer cannot measure things.

show 6 replies
ozimtoday at 4:15 PM

Sounds like we agree.

Bunch of stuff is done for us. Using postgres having indexes correct - is not premature optimization, just basic stuff to be covered.

Having double loop is quadratic though. Parallelism is super fun because it actually might make everything slower instead of faster.

davedxtoday at 3:38 PM

"today, performance is mostly about architectural choices, and it has to be given consideration right from the start"

This doesn't make sense. Why is performance (via architectural choices) more important today than then?

You can build a snappy app today by using boring technology and following some sensible best practices. You have to work pretty hard to need PREMATURE OPTIMIZATION on a project -- note the premature there

show 5 replies
tananaevtoday at 2:40 PM

With modern tools it should be pretty easy to build scalable solutions. I take premature optimization as going out of your way to optimize something that's already reasonable. Not that you should write really bad code as a starting point.

show 2 replies
ghosty141today at 3:02 PM

What's the problem with SOLID? It's very very rare that I see a case where going against SOLID leads to better design.

show 5 replies
jnpnjtoday at 3:35 PM

It's a very interesting topic. Even when designing a system, how to modularize, it's healthy to wait until the whole context is in sight. It's a bit of a black art, too early or too late you pay some price.

xnxtoday at 2:59 PM

> making your code more complicated and still slower than if you thought about performance at the start.

Not if your optimization for performance is some Rube Goldberg assemblage of microservices and an laundry list of AWS services.

show 2 replies
NikolaosCtoday at 3:37 PM

Spent 6 months last year ripping out an abstraction layer that made every request 40ms slower. We profiled, found the hot path, couldn't fix it without a rewrite. The "optimize later" school never tells you later sometimes means never

cogman10today at 2:52 PM

Completely agreed here [1].

And as I point out, what Knuth was talking about in terms of optimization was things like loop unrolling and function inlining. Not picking the right datastructure or algorithm for the problem.

I mean, FFS, his entire book was about exploring and picking the right datastructures and algorithms for problems.

[1] https://news.ycombinator.com/item?id=47849194

throwaway5752today at 3:30 PM

"Premature optimization is the root of all evil"

Decades in, this is the worst of all of them. Misused by laziness or malice, and nowhere near specific enough.

The graveyard of companies boxed in by past poor decisions is sprawling. And the people that made those early poor decisions bounce around field talking about their "successful track record" of globally poor and locally good architectural decisions that others have had to clean up.

It touches on a real problem, though, but it should be stricken form the record and replaced with a much better principle. "Design to the problem you have today and the problems you have in 6 months if you succeed. Don't design to the problems you'll have have next year if it means you won't succeed in 6 months" doesn't roll off the tongue.

show 1 reply
jollyllamatoday at 3:22 PM

You ARE going to need it.

enraged_cameltoday at 2:58 PM

>> Today, late optimization is just as bad as premature optimization, if not more so.

You are right about the origin of and the circumstances surrounding the quote, but I disagree with the conclusion you've drawn.

I've seen engineers waste days, even weeks, reaching for microservices before product-market fit is even found, adding caching layers without measuring and validating bottlenecks, adding sharding pre-emptively, adding materialized views when regular tables suffice, paying for edge-rendering for a dashboard used almost entirely by users in a single state, standing up Kubernetes for an internal application used by just two departments, or building custom in-house rate limiters and job queues when Sidekiq or similar solutions would cover the next two years.

One company I consulted for designed and optimized for an order of magnitude more users than were in the total addressable market for their industry! Of that, they ultimately managed to hit only 3.5%.

All of this was driven by imagined scale rather than real measurements. And every one of those choices carried a long tail: cache invalidation bugs, distributed transactions, deployment orchestration, hydration mismatches, dependency array footguns, and a codebase that became permanently harder to change. Meanwhile the actual bottlenecks were things like N+1 queries or missing indexes that nobody looked at because attention went elsewhere.

show 2 replies
tonymettoday at 3:23 PM

The wheel is a premature optimization to someone who never figured out how to build one.

tehjokertoday at 2:50 PM

I would venture that this statement is not true for library authors. Performance is a large factor in competitive advantage, especially in domains like image analysis or processing large corpuses of text etc.

In these domains, algorithm selection, and fine tuning hot spots pays off significantly. You must hit minimum speeds to make your application viable.