4 ms·
So, interesting and all, but it ignores the main reason for the advice to build it first, then optimize for performance, which is that if you build everything f
by rossdavidh 7y ago
So, interesting and all, but it ignores the main reason for the advice to build it first, then optimize for performance, which is that if you build everything for performance from the beginning, you end up with a lot of code that is optimizing for performance of something that isn't the bottleneck. In other words, performance that doesn't show up in the user's experience, because something else is the main delay.
Now, if all that meant was that the programmer has to do some more work, and you aren't worried about paying more for the software, this may not matter, but that is far from the only (or even most important) result of optimizing everything for performance. Instead, what you get is code that is much longer, and more complex, and therefore harder to update, and more likely to be buggy.
For example, one common thing you have to do to get performance, is to cache values in multiple places, instead of looking them up every time. This can result in big improvements to software performance if done in the places which are the current limiting step, but now you have to make sure you invalidate the cache correctly. In particular, if you don't, you get stale values in the cache, which is to say false data.
If you make a system with cacheing all over the place, it will be very hard to make changes correctly, which means sometimes they will get made incorrectly. In mission-critical systems, this is even less acceptable than elsewhere.
It's not just "I don't feel like optimizing". More often, it's the cost of optimizing is not worth the benefit, for this particular part of the code. How do you know what spots in the code it's worth it? You don't optimize, at first, and then see which two or three spots in the system are rate-limiting.
- phkahler 7y ago>> For example, one common thing you have to do to get performance, is to cache values in multiple places, instead of looking them up every time. This made me cringe. This is filling out a form. It could conceivably be a single record (or small set) in memory that gets committed/updated somewhere else in the background. Overly complicated solutions for simple problems are one of the primary things that kills performance. You don't have to optimize everything for performance, you just have to realize it's a primary feature and avoid doing anything that kills it. We carry super computers in our pockets, you don't have to write complex game code to get performance these days, just don't write shitty things.
- hinkley 7y agoI had an overly long conversation where someone was hand wringing about how and when we pull data to populate the list of states and territories of the US (the fact that the address had to be inside the US had legal standing). I insisted, and probably still do, that since this list hasn’t changed since World War II, odds were really good that the server would reboot before the next change was made, and so looking it up at startup should be just fine.
- hacker_9 7y agoThis is a non realistic reply, as if optimisation is something that can be tacked on after. The truth is you have to walk the fine line between performance and maintenance. It's good to plan ahead and be able to optimise on the bigger picture early, so the design can go through several iterations and code reviews and therefore be trustworthy at the end. Your example of caching is almost basic programming, maintainable code also caches values after calculation for use elsewhere. You don't not cache the results of a database query and pass it around, that's just spaghetti. In reality you have to break out your design into components that can later be rewritten one at a time in order to eek out performance. Easier said then done, but at a high level this first means keeping your big areas (UI, database queries, File IO, networking) separate, and work out the infrastructure from there.
- defined 7y agoeke
- xtian 7y agoMost performance problems come from incidental complexity and programming techniques which don't take into account what the actual hardware is doing. Your focus should not be on tactical optimizations like caching but rather on expanding your understanding of the system as a whole in order to devise simpler and more efficient solutions to problems. Look into "data-oriented design" for more info on this. In the modern business environment, time is most often not allocated for optimization after functionality is complete. And even when it is, if performance is completely ignored throughout the development process, your options for improving it at the end are severely limited.
- mcguire 7y agoThis comment is 1. True. 2. The primary reason that most software is painful to use and occupies significantly more resources than strictly necessary. Programmers, like everyone else, focus on their own pain spots rather than the issues of others. If you don't at least think about optimizing at first, you won't ever do it.
- stickfigure 7y agoSoftware like this doesn't get written in someone's garage. There was almost certainly a team behind it, including a dedicated product manager. The product manager made a decision not to prioritize performance. On one hand, it seems a clear failure. On the other hand, it's hard to judge these kinds of decisions from the outside. The product seems to be successful; the customer paid for it and installed it in ambulances. Maybe if they'd focused on performance instead of adding feature XYZ, or increased the price by adding a faster CPU, the customer would have bought something else. Your competition checks more boxes, therefore must be better! Mostly when I see shitty software, I think not "who wrote this?" but "who bought this?"
- tibbon 7y agoThis isn't premature optimization however. It's having some reasonable SLOs that must be measured throughout development and met. To say that the average button response has to be within 20ms, and the 99% slowest within 50ms is pretty reasonable, and can be measured reasonably easily in a test suite.
- rossdavidh 7y agoSure. But that implies you make it (without everything optimized for performance), measure it, and then make the things which are slow enough to matter, faster. Which sounds just like avoiding premature optimization.
- defined 7y agoBut if you ignore the performance aspects of architecture and build, by the time you try to meet performance specs it is likely too late.
- TeMPOraL 7y ago> Instead, what you get is code that is much longer, and more complex, and therefore harder to update, and more likely to be buggy. I'm gonna repost a chart I made previously[0][1]. Spectrum of performance: LO |---*-------*--------*------------*-------| HI ^ ^ ^ ^ | | | |_root of all evil if premature | | |_you should be here | |_you can be here if you don't do stupid things |_you are here Tricks like denormalizing your data model ("cache values in multiple places") start somewhere around the "you should be here" point. But in any typical program there's plenty of stuff to be done left of that point, and those things don't make your code more complex or longer. They only require care and willingness from the software vendor. -- [0] - https://news.ycombinator.com/item?id=20389856 https://news.ycombinator.com/item?id=20389856 [1] - https://news.ycombinator.com/item?id=20520605 https://news.ycombinator.com/item?id=20520605
- unrealhoang 7y agoUsually, it's more like this: LO |---*------------------*----*--*-| HI ^ ^ ^ ^ | | | |_root of all evil if premature | | |_you should be here | |_you can be here if you don't do stupid things |_you are here
- dahart 7y agoThe point here is not to optimize prematurely, the point is to make responsiveness a design requirement, because it is. You haven't even built it in the first place if it takes more that 100ms to provide any visible feedback to a user input, and you can't even start optimizing until you're already meeting requirements. Once you meet requirements, then by all means pick and choose your optimization battles carefully. To me it seems like Knuth's comment is taken out of context more often than not. He wasn't trying to give people a free pass to make things as slow as possible and ignore system performance. He was assuming that you're making reasonable choices, and not doing overtly stupid things like running the inner loop of your screen drawing in Python, just because it's easy. People always seem to forget the 2nd sentence of the premature optimization quote too: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."
- rossdavidh 7y agoSure, but to know that the critical 3% is, you typically need to first build it, and then measure it. Only in rare cases is it so blindingly obvious that the part you are working on will be in the critical 3%; nearly always, you need to actually measure first. To be able to measure, you must first build.
- dahart 7y agoI can agree with everything you said, but I don’t think there’s really the paradox here or chicken-egg problem that you’re implying. It’s not difficult to make design decisions before building based on the specs of your components. It’s not hard to know that filling pixels via a scripting language or waiting on a synchronous internet request is going to hose your responsiveness. It is possible to make reasonable design decisions before you build, and to reach responsiveness before you optimize. The main reason people fail to reach responsiveness is for lack of making responsiveness an up-front requirement, it’s not for lack of optimization.
- cookiecaper 7y agoThe key component you're missing here is the role of performance in overall design and architecture. If responsiveness is a goal, as it should be in any GUI but especially must be in a system intended for use in medical emergencies, there are high-level decisions that can be made to keep things in the right ballpark. One of these decisions may be "the interface should never have to wait for a network response", for example. The process of micro-optimizing specific segments of program code still needs to depend on actual benchmarks and measurements, but the value of reasonable and experienced system architecture that considers the actual requirements of the problem domain cannot be overstated. You're sunk from the get-go if you make the wrong tradeoffs here. Unfortunately, the industry is mostly populated by clowns who are just blistering to get the hottest buzzword listed on their resume, very frequently rising up to the point of blatant professional misconduct. This leads to many truly absurdist design decisions that sink projects long before the first chunk of code goes into production.
- jasonlotito 7y ago> So, interesting and all, but it ignores the main reason for the advice to build it first, then optimize for performance, which is that if you build everything for performance from the beginning, you end up with a lot of code that is optimizing for performance of something that isn't the bottleneck. In other words, performance that doesn't show up in the user's experience, because something else is the main delay. This isn't a question of optimizing something that doesn't need optimizing. It's about making fundamental choices from the beginning that are optimized and won't need to be optimized later. It's the choice between using native code v.s. electron to build your app. You can make the argument that electron might be better for various reasons, but if you choose to go native, that's an optimization step you are taking. Basically, you are saying "Premature optimization is the root of all evil" without including the rest of the quote and misreading what Knuth wrote. > We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. There are certain fundamental things you can do, optimization you can do before you ever write the software. This comes from experience. > Instead, what you get is code that is much longer, and more complex, and therefore harder to update, and more likely to be buggy. No, this does not have to happen. In fact, if you build it first and worry about optimization later, you're more likely to end up in this state. > How do you know what spots in the code it's worth it? Experience. You get that from experience with code. And you can't get that experience if you are frequently changing jobs.
- defined 7y agoThank you for writing this. So many people don’t get it. You cannot tack performance on after the fact like some aftermarket pony car part if the performant architecture is not there to support it.
- defined 7y agoThis is too narrow a focus. Performance starts at the architecture level and can’t be bolted on after the fact.