Remix.run Logo
Megranium 4 hours ago

Huh, I've always understood that quote very differently, with emphasis on "premature" ... not as in, "don't optimize" but more as in "don't optimize before you've understood the problem" ... or, as a CS professor of mine said "Make it work first, THEN make it work fast" ...

lokar 4 hours ago | parent | next [-]

And if you know in advance that a function will be in the critical path, and it needs to perform some operation on N items, and N will be large, it’s not premature to consider the speed of that loop.

lokar 4 hours ago | parent | next [-]

Another thought: many (most?) of these "rules" were before widespread distributed computing. I don't think Knuth had in mind a loop that is reading from a database at 100ms each time.

I've seen people write some really head shaking code that makes remote calls in a loop that don't actually depend on each other. I wonder to what extend they are thinking "don't bother with optimization / speed for now"

kstrauser 3 hours ago | parent | next [-]

First, I agree with what you're saying.

But second, I'd remove "optimization" from considering here. The code you're describing isn't slow, it's bad code that also happens to be slow. Don't write bad code, ever, if you can knowingly avoid it.

It's OK to write good, clear, slow code when correctness and understandability is more important that optimizing that particular bit. It's not OK to write boneheaded code.

(Exception: After you've written the working program, it turns out that you have all the information to make the query once in one part of the broader program, but don't have all the information to make it a second time until flow reaches another, decoupled part of the program. It may be the lesser evil to do that than rearrange the entire thing to pass all the necessary state around, although you're making a deal with the devil and pinky swearing never to add a 3rd call, then a 4th, then a 5th, then...)

rob74 4 hours ago | parent | prev [-]

If you really have a loop that is reading from a database at 100ms each time, that's not because of not having optimized it prematurely, that's just stupid.

patrickthebold 2 hours ago | parent | next [-]

Reminds me of this quote which I recently found and like:

> look, I'm sorry, but the rule is simple: if you made something 2x faster, you might have done something smart if you made something 100x faster, you definitely just stopped doing something stupid

https://x.com/rygorous/status/1271296834439282690

heliumtera 3 hours ago | parent | prev | next [-]

Got it. What about initiating a 800mb image on a CPU limited virtual machine that THEN hits a database, before responding to a user request on a 300ms roundtrip? I think we need a new word to describe the average experience, stupidity doesn't fit.

lokar 4 hours ago | parent | prev [-]

And yet... :)

I think there is just a current (I've seen it mostly in Jr engineers) that you should just ignore any aspect of performance until "later"

lokar 3 hours ago | parent [-]

and, I guess, context does matter. If you need to make 10 calls to gather up some info to generate something, but you only need to do this once a day, or hour, and if the whole process takes a few seconds that's fine, I could see the argument that just doing the calls one at a time linearly is simpler write/read/maintain.

senfiaj 2 hours ago | parent | prev | next [-]

From my understanding you still need to care care about the algorithms and architecture. If N is sufficiently large, you should pick O(N) algorithm over O(N^2). But usually there is a tradeoff, simple code (or hiding something behind some abstraction) might be easier to understand and maintain, but it might work slower with large input data and vice versa. I would rather write code that will be easier to optimize if there is some bottleneck than to optimize it overagressivelly. Also, different code needs different kind of optimization. Sometimes the code might be more IO heavy (disk / DB or network), for this type of code, the IO operation planning and caching is more critical than the optimization of the raw CPU time. Sometimes the input is too small to have any significant performance effects, and, what's paradoxical, choosing smarter algorithms might even hurt performance (alongside the maintanability). For example, for 10 - 100 items a simple linear scan in an array might be faster than using a O(log n) binary search tree. It's also well known that faster executable code (regardless of being hand written, machine generated, high level or machine code) usually has larger size (mostly because it's more "unrolled", duplicated and more complex when advanced algorithms are used). If you optimize the speed everywhere, the binary size tends to increase, causing more cache misses, which might hurt the performance more than improve. This is why some profiling is often needed for large software than simply passing O3.

redbar0n 3 hours ago | parent | prev [-]

Just remember Rob Pike's 1st rule: don't assume where bottlenecks will occur, but verify it.

ummonk 3 hours ago | parent [-]

I've worked on optimizing modern slow code. Once you optimize a few bottlenecks it turns out it's very hard to optimize because the rest of the time is spread out over the whole code without any small bottlenecks and it's all written in a slow language with no thought for performance.

vbezhenar 4 hours ago | parent | prev | next [-]

We will optimize it later, we don't have time for that right now, it seems it works fast enough for our needs right now.

"Later" never comes and all critical performance issues are either ignored, hot-patched externally with caches of various quality or just with more expensive hardware.

Nemi 3 hours ago | parent | next [-]

While what you say is often true, it is a different problem and does not change the fact of the prior posters.

zygentoma 2 hours ago | parent | prev [-]

My favourite quote for that is:

Broken gets fixed, but crappy stays forever

mort96 4 hours ago | parent | prev | next [-]

Plenty of people seem to understand it as, "don't even think about performance until someone has made a strong enough business case that the performance is sufficiently bad as to impact profits".

artyom an hour ago | parent | prev | next [-]

I agree with you. "Premature" is the keyword. Bloated software is the result of not having the intention to optimize it at all.

DarkCrusader2 4 hours ago | parent | prev | next [-]

well you see, in corporate (atleast in big tech), this is usually used as a justification to merge inefficient code (we will optimize it later). That later never comes, either the developers/management moves on or the work item never gets prioritized. That is until the bad software either causes outages or customer churn. Then it is fixed and shown as high impact in your next promo packet.

ekropotin 4 hours ago | parent | prev | next [-]

IDK if it can be applied in all situations.

Sometimes, especially when it comes to distributed systems, going from working solution to fast working solution requires full blown up redesign from scratch.

bdangubic 3 hours ago | parent | prev | next [-]

> Make it work first, THEN make it work fast

1. I have seen too many "make it work first" that ended up absolute shitshow that was notoriously difficult to do anything with. You can build the software right the first time

2. The "fast" part is what I think too many people are focusing on and in my experience the "THEN" part is always missing resources utilization and other types of inefficiency that are not necessarily related to speed. I have seen absolute messes of software that work really fast

rco8786 3 hours ago | parent | prev [-]

Ditto here