5 ms·
I think the problem with the quote is that everyone forgets the line that comes after it. We should forget about small efficiencies, say about 97% of the tim
by godelski 1y ago
I think the problem with the quote is that everyone forgets the line that comes after it.
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
vvvvvvvvvv
Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified.
^^^^^^^^^^
This makes it clear, in context, that Knuth defines "Premature Optimization" as "optimizing before you profile your code"
@OP, I think you should lead with this. I think it gets lost by the time you actually reference it. If I can suggest, place the second paragraph after
> People always use this quote wrong, and to get a feeling for that we just have to look at the original paper, and the context in which it was written.
The optimization part gets lost in the middle and this, I think, could help provide a better hook to those who aren't going to read the whole thing. Which I think how you wrote works good for that but the point (IMO) will be missed by more inattentive readers. The post is good also, so this is just a minor critique because I want to see it do better.
https://dl.acm.org/doi/10.1145/356635.356640 https://dl.acm.org/doi/10.1145/356635.356640
(alt) https://sci-hub.se/10.1145/356635.356640 https://sci-hub.se/10.1145/356635.356640
- Swizec 1y agoAmdahl’s Law is the single best thing I learned in 4 years of university. It sounds obvious when spelled out but it blew my mind. No amount of parallelization will make your program faster than the slowest non-parallelizable path. You can be as clever as you want and it won’t matter squat unless you fix the bottleneck. This extends to all types of optimization and even teamwork. Just make the slowest part faster. Really. https://en.wikipedia.org/wiki/Amdahl%27s_law https://en.wikipedia.org/wiki/Amdahl%27s_law
- godelski 1y ago> It sounds obvious when spelled out but it blew my mind. I think there's a weird thing that happens with stuff like this. Cliches are a good example, and I'll propose an alternative definition to them. A cliche is a phrase that's so obvious everyone innately knows or understands it; yet, it is so obvious no one internalizes it, forcing the phrase to be used ad nauseam At least, it works for a subset of cliches. Like "road to hell," "read between the lines," Goodheart's Law, and I think even Amdahl's Law fits (though certainly not others. e.g. some are bastardized, like Premature Optimization or "blood is thicker than water"). Essentially they are "easier said than done," so require system 2 thinking to resolve but we act like system 1 will catch them. Like Amdahl's Law, I think many of these take a surprising amount of work to prove despite the result sounding so obvious. The big question is if it was obvious a priori or only post hoc. We often confuse the two, getting us into trouble. I don't think the genius of the statement hits unless you really dig down into proving it and trying to make your measurements in a nontrivially complex parallel program. I think that's true about a lot of things we take for granted
- chinchilla2020 1y agoanother commonly misinterpreted one is the `shouting fire in a crowded theatre` quote. In it's original context it means the opposite of how people use it today.
- comex 1y agoWell, sort of. The specific point Justice Oliver Wendell Holmes was making is pretty much the same as how it’s used today: some speech is so obviously harmful that it can’t be protected by freedom of speech. The problem is that Holmes was using it as an example of what even “the most stringent protection of free speech” would leave unprotected, and he went on to interpret the First Amendment rather less stringently, ruling that it didn’t protect anti-draft flyers.
- hinkley 1y ago> faster than the slowest non-parallelizable path Rather, than the slowest non-parallelized path. Ultimately you may reach maximum speed on that path but the assumptions that we are close to it often turn out to be poorly considered, or considered before 8 other engineers added bug fixes and features to that code. From a performance standpoint you need to challenge all of those assumptions. Re-ask all of those questions. Why is this part single threaded? Does the whole thing need to be single threaded? What about in the middle here? Can we rearrange this work? Maybe by adding an intermediate state?
- ilc 1y agoInterestingly, you didn't learn the full lesson: When optimizing, always consider the cost of doing the optimization vs. it's impact. In a project where you are looking a 45/30/25 type split. The 45 may actually be well optimized, so the real gains may be in the 30 or 25. The key is to understand the impact you CAN have, and what the business value of that impact is. :) The other rule I've learned is: There is always a slowest path.
- Swizec 1y ago> The key is to understand the impact you CAN have, and what the business value of that impact is. :) Like I tell everyone in system design interviews: AWS will rent you a machine with 32TB of RAM. Are you still sure about all this extra complexity?
- naniwaduni 1y ago... to the tune of about 10 cents a second, yeah. If you can hire a dev team to optimize one of those out, you plausibly come out ahead (well, vs face value).
- what 1y agoHow do you come out ahead hiring an entire team to save $6/hour?
- naniwaduni 1y agoThat's $6/minute, $360/hour. Granted, if you're using it at a scale approaching FTE costs, you probably want at least some reserved capacity and you're likely not paying face value, but then the comparison was never going to be rigorous anyway.
- what 1y agoOh, I’m an idiot. Sorry, ignore me.
- chinchilla2020 1y agoThere is more to it than that. 1. Decide if optimization is even necessary. 2. Then optimize the slowest path
- nurettin 1y agoThere is also the "death by a thousand cuts" kind of slowness that accrues over time and it doesn't really matter where you start peeling the onion and the part you started is rarely the best.
- adrian_b 1y agoWhile Amdahl’s Law is very important, its practical effects are very frequently overestimated, at least as frequently as Knuth is misquoted. Simple problems, e.g. solving a system of equations, will usually include some non-negligible sequential part, which, according to Amdahl’s Law will limit the amount of speed-up provided by hardware parallelism. On the other hand, complex problems, e.g. designing an integrated circuit, can usually be decomposed in a very great number of simpler subproblems that have weaker dependencies between them, than between the parts of a subproblem, so that by distributing the execution of the simple subproblems over parallel hardware that executes sequentially each subproblem you can obtain much greater acceleration factors than when attempting to parallelize the execution of each simple subproblem. With clever decomposition of a complex problem and with good execution planning for its subtasks, it is much easier to approach the performance of an embarrassingly parallel problem, than when trying to find parallel versions of simple algorithms, whose performance is frequently limited to low values by Amdahl’s Law. Amdahl’s Law frequently prevents you from reducing the execution time of some task from 1 minute to 1 second, but it normally does not prevent you from reducing the execution time of some task from 1 year to 1 week, because a task so complex to have required weeks, months or years before parallelization normally contains a great enough number of weakly-coupled subproblems.
- p_l 1y agoI find Amdahl's Law very useful for parallelizable work as well. Or at least, I find it trivially scalable to parallel case. Often it helped for me in modeling how interconnect would be a possibly limiting element for a task even for embarassingly parallel tasks.
- wiz21c 1y agoBefore optimizing, I always balance the time I'll need to code the optimization and the time I (or the users of my code) will effectively gain once the optimization is there (that is, real-life time, not CPU time). If I need three weeks to optimize a code that will run for 2 hours per month, it's not worth it.
- bruce343434 1y agoBut by not optimizing, you don't grow your profiling/optimizing skills and you miss out on a reduction in how long optimizing takes you for future work. Therefore many more codes will not meet the threshold and your skills may not grow for a long time.
- wiz21c 1y agoYou couldn't know, but my job is 50% about optimizing computational workloads. But many times, when questionning my users, it happens that they want an optimisation for some code that will run 2 or 3 times. So eventhough they'll have to wait a week for the computation to run, it'll take me just as much time to make the optimisation run :-) But if code happens to be used 10 times a week and takes about a day or two to run, it's a no brainer: spending a month optimizing for 10% speed increase is worth it !
- bluGill 1y agoThe one question that needs to be asked is would the users run it more often if it didn't take so long? There is nothing a computer can do that a room full of clerks in 1800 couldn't do, but the runtime would be so slow (or the cost in clerks so high) that nobody dared ask those questions. Exercise for the reader, given an unlimited budget to hire 1800's clerks how many FFS could you achieve running doom. (obviously the number is too low to make the game playable)
- sethammons 1y agoA former boss: an optimization made at a non-bottleneck is not an optimization.
- mholub 1y agoit's more nuanced: you're still releasing resources - so you might not become faster overall but you can compute more in the same time later if necessity arises (althougth that might be somewhat premature but can be good for library code - so it becomes more applicable in different environments) and there are some rare but tricky scenarios like: hardware is mobile phone: app seem to be bottlenecked on arithmetics according to the profiler, so it feels obvious to start optimization there in reality what happens - hardware has limit on power, so it can't give full power to CPU, GPU and memory all at the same time since app uses too much memory - it has to redirect power there, also memory emits heat, so CPU becomes throttled By optimizing memory, everything runs colder -> CPU gets more power, can run sustained higher frequencies - app becomes faster
- sethammons 1y agoAnd if the app becoming faster doesn't mean anything because the app is waiting for user input the whole time, it was a lot of work for naught. Perhaps restated: If the optimization cannot be felt (ie, impact on the product experience), it is not an optimization worth pursuing.
- eru 1y ago> And if the app becoming faster doesn't mean anything because the app is waiting for user input the whole time, it was a lot of work for naught. Oh, that might still be good for battery life (or power consumption in general).
- progmetaldev 1y agoThis one is more dangerous, as there may be backend resources in use that could be optimized, which could drop costs drastically. This may not change anything for your users, but is definitely worth exploring when it comes to getting the most out of your investment.
- hinkley 1y agoIt is exactly this "lulled into complacency" that I rail against when most people cite that line. Far too many people are trying to shut down down dialog on improving code (not just performance) and they're not above Appeal to Authority in order to deflect. "Curiosity killed the cat, but satisfaction brought it back." Is practically on the same level. If you're careful to exclude creeping featurism and architectural astronautics from the definition of 'optimization', then very few people I've seen be warned off of digging into that sort of work actually needed to be reined in. YAGNI covers a lot of those situations, and generally with fewer false positives. Still false positives though. In large part because people disagree on what "The last responsible moment" in part because our estimates are always off by 2x, so by the time we agree to work on things we've waited about twice as long as we should have and now it's all half assed. Irresponsible.
- godelski 1y agoI'm with you, and been on a bit of a rampage about it lately. Honestly, just too much broken shit, though I'm not sure what the last straw was. A big thing I rail against is the meaning of an engineer and that our job is about making the best product, not making the most profitable product (most times I bring this up someone will act like there's no difference between these. That itself is concerning). The contention between us engineers and the business people is what creates balance, but I'm afraid we've turned into yesmen instead. Woz needs Jobs, but Jobs also needs Woz (probably more than the other way around). The "magic" happens at the intersection of different expertise. There's just a lot of weird but subtle ways these things express themselves. Like how a question like "but what about x problem" is interpreted as "no" instead of "yes, but". Or like how people quote Knuth and use it as a thought terminating cliche. In ML we see it with "scale is all you need." In effect, by choosing to do things the easy way we are choosing to do things the hard way. Which this really confuses me, because for so long in CS the internalization was to "be lazy." Not in the way that you put off doing the dishes now but in the way that you recognize that doing the dishes now is easier than doing them tomorrow when you 1) have more dishes 2) the dishes you left out are harder to clean as the food hardens on the plate. What happened to that "efficient lazy" mindset and how did we turn into "typical lazy"?[0] [0] (I'm pretty sure I need to add this) https://en.wikipedia.org/wiki/Rhetorical_question https://en.wikipedia.org/wiki/Rhetorical_question
- foobiekr 1y agoA lot of people are still thinking of Knuth's comment as being about just finding the slow path or function and making it faster. What Knuth has talked about, however, and why any senior engineer who cares about performance has either been taught or discovered, is that most real optimization is in the semantics of the system and - frankly - not optimizing things but finding ways not to do them at all. Tuning the JSON parser is not nearly as effective as replacing it with something less stupid, which is, in turn, not nearly as effective as finding ways to not do the RPC at all. Most really performant systems of a certain age are also full of layer violations for this reason. If you care about performance (as in you are paid for it), you learn these realities pretty quickly. You also focus on retaining optionality for future optimizations by not designing the semantics of your system in a way that locks you permanently into low performance, which is unfortunately very common.
- sfn42 1y agoWell said. Another example of this is using the right algorithm for the job. I see a lot of code like let's say you have two lists and you need to go through the first one and find the corresponding element by id in the second. The naive implementation uses linear search of the second list, making the algorithm O(n^2). This will stall and take hours, days or longer to run when the lists get large, say into the tens to hundreds of thousands of elements. If both lists come from your own database then you should have used a foreign key constraint and had the database join them for you. If you can't do that, let's say one or both lists come from a third-party api, you can create a dictionary(hashmap) of the second list to allow O(1) lookup rather than O(n) which brings your full algorithm's complexity to O(n). Now the you can have millions of elements and it'll still run in milliseconds or seconds. And if this is something you need to do very often then consider storing the second list in your database so you can use a join instead. Avoid doing the work, as you say. These are the most common mistakes I see people make. That and situations where you make one request, wait for a response, then use that to make another request, wait for response and so on. You don't need a profiler to avoid this type of problem, you just need to understand what you're doing at a fundamental level. Just use a dictionary by default, it doesn't matter if it might be slightly slower for very small inputs - it'll be fast enough and it'll scale.
- tialaramex 1y ago> This makes it clear, in context, that Knuth defines "Premature Optimization" as "optimizing before you profile your code" As with that Google testing talk ("We said all your tests are bad, but that's not entirely true because most of you don't have any tests"), the reality is that most people don't have any profiling. If you don't have any profiling then in fact every optimisation is premature.
- lisper 1y agoThe operative word was always "premature". As with everything, whether or not a particular optimization is worthwhile depends on its ROI, which in the case of software depends on how often your code is going to be run. If you are building a prototype that's only going to run once, then the only optimizations that are worthwhile are the ones that speed things up by times comparable to the time it take to write them. On the other hand, if you're writing the inner loop of an LLM training algorithm, a 1% speedup can be worth millions of dollars, so it's probably worth it even if it takes months of effort.
- jerf 1y agoYou can almost simplify it to simply observing that PREMATURE optimization is not the same as OPTIMIZATION. Most people I see who get offended are reacting to the claim that optimization is never useful. But it's pretty easy to knock that claim over. I don't deny that plenty of people use adjectives very sloppily, and that much writing is improved by just ignoring them, but Knuth is not one of them.
- psychoslave 1y agoPreprofiling optimisation is stab in the dark. Isn't that more clear and at least as concise as the original one, also using some idiomatic metaphor while avoiding the reference to mythical dark forces.
- Mawr 1y agoBy definition anything premature is going to be bad. It's not any kind of an insight.
- godelski 1y agoA pet peeve of mine is how common it is for people to ignore qualifying words. Like you can say "most people do 'x'" and you can guarantee if you post that online people will come out of the woodwork saying "I don't do 'x'". Sure, the most claims can often be inaccurate, but those types of responses aren't helpful and aren't meaningfully responsive even if true. "Most" is just a very different word from "all". It implies a distribution but idky we often think things are discrete or binary. I also see ignoring qualifiers as a frequent cause for online arguments. They're critical words when communicating and dropping them can dramatically change what's being communicated. And of course people are fighting because they end up talking about very different things and don't even realize it. While I agree with you, that it's common for people to use these words sloppily, I think it is best to default to not ignore them. IME, in the worst case, it aids in communication as you get clarification.
- renecito 1y agotoo late, all the slackers got promoted and now are demanding to keep pushing features no one is asking about.
- godelski 1y agoSame is true for lots of things. Classic example is we are so leetcode obsessed because all the people that were leetcode obsessed got hired and promoted. We've embraced p-hacking, forgetting Goodhart's Law (and the original intention of leetcode style interviewing. It's just the traditional engineering interview, where you get to see how the interviewee problem solves. It is less about the answer and more about the thought process. It's easy to educate people on answers, but it is hard to teach someone how to think in a different framework... (how much money do we waste through this and by doing so many rounds of interviewing?))
- jayd16 1y agoYes but the second half of the second half is "only after that code has been identified." So the advice is still 'don't waste your time until you profile.'
- neves 1y agoI'm appalled by the number of developers that don't know that profilers exist. BTW, my junior developers don't know what a debugger is.
- sitkack 1y agoYou have joined a noble line of Knuth Quote Expanders, https://hn.algolia.com/?dateRange=all&page=3&prefix=true&query=%22should%20not%20pass%20up%20our%20opportunities%20in%20that%20critical%22&sort=byDate&type=comment https://hn.algolia.com/?dateRange=all&page=3&prefix=true&que... They are all worth reading.
- godelski 1y agoTwice in the last 2 months. I'm not sure if that's a good thing or a bad thing hahaha