6 ms·
He is refuting a version of "premature optimization is the root of all evil" that I have never heard in practice: "Mostly this quip is used defend sloppy decis
by mwfunk 11y ago
He is refuting a version of "premature optimization is the root of all evil" that I have never heard in practice:
"Mostly this quip is used defend sloppy decision-making, or to justify the indefinite deferral of decision-making."
I have never heard it used in this context. Sometimes I've heard it used as a gentle way to suggest to someone that they are going off in the weeds and need to refocus on what they should be focused on, but usually I've just heard it used as it was originally intended by Knuth.
Optimization often involves making code less clear, more brittle, or with a more pasta-like organization. Frequently optimization requires writing code that if looked at out of context, doesn't make sense or might even look wrong.
When these sorts of optimizations need to be made, they should be made only as needed (and documented). It shouldn't be done without knowing whether or not a particular code path is even a bottleneck in the first place, and it shouldn't be done if speeding up that particular bottleneck wouldn't make the software better in any tangible way. That's all the phrase means.
- adrusi 11y agoIn a lot of circles, especially where web developers are involved, you'll get called out for premature optimization for spending any mental energy worrying about memory usage or bandwidth. The idea is that computers are fast, so we can just do whatever we want, and worry about it if it becomes a problem. The result is that it becomes a problem, then gets patched up to meet whatever bare minimum performance standards the company has (or the deadline arrives and it's released unoptimized) and we end up with the absurdly heavy and resource-greedy software we see today.
- hire_charts 11y agoYes, this is where, in practice, I've seen the adage used incorrectly. Even when Knuth isn't quoted directly, the idea that "premature optimization" is inherently a bad thing has led many a web developer down the path of terrible architecture decisions. So I understand Duffy's point exactly. It's not that all issues are preventable. It's that you can prevent a lot of them with just a little extra work up front. It's a misuse of Knuth's original point, which has much more to do with how brittle and incomprehensible "optimized" code can become.
- ubernostrum 11y agoI prefer the development order of make it work, make it correct, then make it fast. Expresses a similar idea, but in terms of priorities instead of "don't do that at all".
- vmorgulis 11y ago> Expresses a similar idea, but in terms of priorities instead of "don't do that at all". The programming language affects a lot the criterion. Some are known to be "correct" (like Haskell), others "fast" (like C) ... Given an infinite amount of time, I suppose the three can be reached in any language.
- Swizec 11y agoIt's a cost optimization. How much engineer time does it take to shave 0.2 seconds off of an action that's got a 0.3s animated transition anyway? How much engineering does it take to care about the memory footprint of a website users are going to close in 5 minutes anyway? Most of the time, the answer is "Too much, not worth it". Some of the time the answer is "Let's do it". Knowing which situation you are in is key. Ideally, I should write code for readability and maintainability and let the compiler and runtime worry about optimizations.
- kuschku 11y agoAnd that’s when people start using script blockers and block many CSS features just to be able to load + display webpages in ping + 16ms.
- yongjik 11y agoNo opinion about the rest of the argument, but a 300ms animated transition is looooooong. It will be noticed by basically everybody and annoy a good number of them. The only good reason I can think of is that you're somehow stuck with 300ms+ delay anyway, so you provide an animation so that the users don't think "WTF? I just clicked on it and why is nothing happening?" But if you can shave off 0.2 seconds then you can probably get rid of the animation altogether!
- Swizec 11y agoYou'd be surprised by how many people think those 300ms animated transitions are a good thing. I think they're terrible. You'd also be surprised by how many people will completely misunderstand your UI and get confused by things popping around magically, if the transitions are too fast or inexistent. You have to build a UI/UX that your typical user will enjoy and be able to use, not a UI/UX that your nerdy friends are going to love. (unless they're your target users)
- mrob 11y agoThe only good UI animations I've seen were in Metacity (window manager for Gnome 2). It would move windows instantly, but also provide a transparent trail showing the path they would have taken if they had been animated traditionally. It let you continue working without delay if you knew what you were doing while still helping beginners.
- nostrademons 11y agoFrom a business perspective, this is probably the right decision. Businesses are interested in marginal gains, i.e. they want performance improvements only if those will lead to more customers or customers that pay more money. Any extra effort is better spent on things that will get more customers or more money per customer. From an overall social welfare pesrpective, there is something to be said for going above and beyond the customer's minimum standard. Indeed, most of the work that goes on at big companies is of this type (it's no coincidence that the original author works on the compiler team at Microsoft). Just understand the context in which you work - if the company is going to go under with its current customer base, it's irresponsible to focus on things that are not going to get more customers - and that it can be hard to measure the effectiveness of work that doesn't directly lead to new sales.
- acqq 11y ago> From an overall social welfare pesrpective, there is something to be said for going above and beyond the customer's minimum standard. Indeed, most of the work that goes on at big companies is of this type So do you want to say that MSFT should invest less energy in speeding up the code they produce, because it won't get them more customers or more money?
- nostrademons 11y agoFrom which perspective do you want an answer? A user of Microsoft products, a developer at Microsoft, a shareholder of Microsoft, or an executive of Microsoft? As a user, of course I want Microsoft to invest more in speeding up their products. I also want them to be easier to use, and have all the features that I want, and cost less, and release more frequently. As an engineer, yes, I do want them to invest more in speeding up products. Performance tuning is fun, it's an extra skill that can go on my resume, and it helps me take pride in my work. As a shareholder, hell no are you going to indulge those prima donna engineers and their perfectionist tendencies. I invested in this company to get a return on my investment, and that means more revenue. It's clear that shaving CPU cycles isn't going to get more customers; Windows has been dog-slow compared to competitors ever since the Amiga came out, and it hasn't hurt us so far. That effort would be better invested in getting into new lines of business and building more solutions to capture the enterprise market. As an executive - it's a complicated question. I want our products to be faster, but it's also clear that our customers want them to be easier to use, and have a lot more features, and cost less, and release more frequently. All of those are in conflict with writing performant code with a fixed number of highly-trained engineers. And if I hire more engineers, the code often gets slower, as global optimization opportunities get lost in the communication gaps between workers. OTOH, performance often has intangible benefits in brand loyalty, in increased usage, in word-of-mouth, and in PR. I'd love to be able to quantify these benefits and trade them off against each other, but the point of intangibles is that they are intangible. I'm responsible to shareholders, however, and my gut feeling is that increased performance will not be the deciding factor for most customers. (As just plain old me, the question is completely academic: I am neither a user, employee, executive, or shareholder of Microsoft, so I don't really care what they do.)
- blakeyrat 11y agoWell the salient word in the phrase is "premature". As opposed to optimization after careful observation and measurement, which everybody agrees can and should be done.
- svdree 11y agoBut at the point where you're ready for careful observation and measurement, you've already designed and written your solution, and the amount of room you have for optimization is constrained by the thing you just built. If you want performance, you have to design for performance, not just build the first thing that comes to mind and try to optimize it later.
- deleted 11y ago[deleted]
- dhimes 11y agoInteresting. I always interpreted it as, "Don't sweat the details yet- you don't even know if anybody wants what you are building. Find that out first."
- mark-r 11y agoThe mindset of "fail fast" wasn't a thing when Knuth wrote that statement.
- dhimes 11y agoThis isn't "fail" so much as it is acknowledging that neither you nor your customers will know what they like until they have something to play with.
- mark-r 11y agoMy point was that Knuth wasn't considering that possibility when he wrote the quote. In those times it was assumed that if you were writing software, there was a darn good reason for it. The idea that you might write software that doesn't fulfill a compelling need is a rather modern invention.
- over 11y agoExcept that optimizing cold code is writing software that doesn't fulfill a compelling need.
- crdoconnor 11y ago>In a lot of circles, especially where web developers are involved, you'll get called out for premature optimization for spending any mental energy worrying about memory usage or bandwidth. The idea is that computers are fast, so we can just do whatever we want, and worry about it if it becomes a problem. The result is that it becomes a problem, then gets patched up to meet whatever bare minimum performance standards the company has (or the deadline arrives and it's released unoptimized) and we end up with the absurdly heavy and resource-greedy software we see today. IMHO, this is exactly the kind of thing Donald Knuth was approving of. Given how cheap CPU cycles are, how expensive developers are and that faster code often means more 'unsafe' code, 97% of the time it's more economic to just have the resource-greedy software. Plus, I've seen more than my fair share of premature optimizations that ended up actually causing performance problems and stupid bugs.
- vmorgulis 11y ago> Given how cheap CPU cycles are, how expensive developers are and that faster code often means more 'unsafe' code, 97% of the time it's more economic to just have the resource-greedy software. I agree. I run sloccount in my build system. It gives a cost for manpower. For example: Total Physical (SLOC) = 6,944 Development (Person-Months) = 18.36 Schedule Estimate (Months) = 7.55 Estimated Average Number of Developers = 2.43 Estimated Cost to Develop = $ 206,696 http://www.dwheeler.com/sloccount/ http://www.dwheeler.com/sloccount/ http://vmorgulys.github.io/stackcity/sloccount.html http://vmorgulys.github.io/stackcity/sloccount.html We should count the energy spent by inefficient programs (multiply the number of devices). It could balance that equation as the Moore's Law is ending. I guess Debian (or another distro) if more energy-efficient than Windows (or Android). Edit: beautified sloccount output
- maxxxxx 11y agoI get into discussions like this all the time. With a little thinking ahead you can avoid getting yourself caught in a difficult situation later on. It doesn't mean you should implement the optimization but at least you should allow for it. That could mean a simple API wrapper that can later on be optimized or to do an analysis what would happen if the traffic increased 10x. Unfortunately looking further than the end of the next sprint is disallowed in a lot of people's minds. It's pretty sad that a lot of software "engineers" actively avoid any kind of engineering.
- gnaritas 11y agoIt's not sad, that kind of "thinking ahead" leads too oodles of junk in the code for "someday" features that never get implemented. If your programming style requires thinking ahead to make a feature possible later, then you're better off fixing your style and learning to program better so it costs the same to make the change when it's needed as it does now, then you can put off the change until it's actually needed. Premature architecture is a code smell. Putting in scaffolding for later is a code smell.
- maxxxxx 11y agoI am not talking about actually producing code for "someday" features. I am talking about working towards a goal. Most projects know pretty well where they will be in one or two years (not everyone is Instagram who goes from 0-100 in a year). Based on that knowledge you can make reasonable decisions and trade-offs now. However, I admire your ability to write code without any forethought now that can be used perfectly in whatever form it will be needed later.
- gnaritas 11y ago> Most projects know pretty well where they will be in one or two years I dispute that that is true. They may have a vague idea of a goal, but that's not applicable at the code level in general. > Based on that knowledge you can make reasonable decisions and trade-offs now. We aren't talking about making decisions, we're talking about stubbing out code for future needs, an entirely different thing. Nothing wrong with making reasonable decisions, but there is something wrong with stubbing out code you don't need because you think you'll need it later; if you need it later, add it later. It'll cost the same as adding it now. If you think it's going to cost more later, then revisit your architecture because it shouldn't. The implicit argument for adding it now is that's it's cheaper to add now than later, I'm saying that's nearly always a bunk argument. > However, I admire your ability to write code without any forethought now that can be used perfectly in whatever form it will be needed later. That's not what I said; the cost of change should be the same later as now. That doesn't mean you won't have to make a change, it just means it shouldn't be harder to add later than to add now.
- nyan4 11y ago> web developers That's the problem.
- falsedan 11y ago> Optimization often involves making code less clear, more > brittle, or with a more pasta-like organization. > Frequently optimization requires writing code that if > looked at out of context, doesn't make sense or might > even look wrong. I agree so much with this. It's better to write a sub-optimal implementation for a component which is clear & can be replaced with a more performant version later, when the bottlenecks have been identified + the interface is well-defined and -tested, and the team can accept the maintenance burden of non-obvious code. This does mean you can't skimp on good design, making your project a collection of modular, replaceable components.
- HeyImAlex 11y agoFurther, very often we write code that isn't the code we need to write. I have wasted countless hours on needlessly efficient implementations of the wrong interface, or, on the other end of the spectrum, coming up with the perfect interface for code that will never be used again. Because I like puzzles and optimizing is fun and wiring up business processes is not very fun at all. But that doesn't mean it's a good way to write software. Accept that most of what devs do is fairly mundane, and focus your mental effort where it's actually needed and you'll be a better developer than anyone who obsesses over the performance/elegance/extensibility of every line they write. Obviously it's a spectrum, and it takes balance, but I know which side I'm currently on!
- falsedan 11y ago> I have wasted countless hours on needlessly efficient > implementations of the wrong interface, or, on the other > end of the spectrum, coming up with the perfect interface > for code that will never be used again. SAME HERE
- carussell 11y agoExamples on either side abound. I know I've certainly done enough optimizations that left the code clearer and shorter (despite often being more verbose with naming), while being more performant due to shedding whatever messy, tortured approach was in use before. Enough small gains like this have come out of code where I was the original author that it isn't a case of conceit. Clear and simple code can frequently beat clever code, regardless of which metric you choose to apply from the "performance or understandability" bag.
- TrevorJ 11y agoI think it probably also matters a lot whether or not there's a clear solution. If there's a better than average chance that the optimization strategy is known, and will work then it's probably fine to hold off on it. If the way you are writing the program doesn't lend itself to clear solutions for the performance bottlenecks then that's an issue that should be dealt with right away or you risk throwing out a whole lot of work later on.
- blub 11y agoThen you should spend some more time on HN or reddit and you will definitely hear this. It's bound to pop up sooner or later in topics where programming languages are discussed. Here's a comment where someone says that performance doesn't matter at all if you only have a certain number of users and then they backtrack and qualify their statements: https://news.ycombinator.com/item?id=11245700 https://news.ycombinator.com/item?id=11245700 I have the opposite impression - that many devs are lazy and don't think about optimisation at all. They write slow code by default and hide behind a misquoted Knuth. Your definition is off by the way, writing fast code and doing optimisation doesn't necessarily mean that the code will be less understandable or become brittle. e.g: using range va xrange in Python 2.x when iterating over large ranges - that's a difference of literally one letter. There are of course other examples.
- crdoconnor 11y ago>using range va xrange in Python 2.x when iterating over large ranges - that's a difference of literally one letter. Which literally makes no noticeable difference 97% of the time. I wouldn't necessarily complain if you did that to my code as part of a broader refactor but if the range is small you're not doing anybody any favors.
- jlebar 11y agoYour definition is off by the way, writing fast code and doing optimisation doesn't necessarily mean that the code will be less understandable or become brittle. OP said Optimization often involves making code less clear, more brittle Seems you're arguing against a straw man here.
- blub 11y agoNot quite. * OP is arguing that optimisation is usually problematic from multiple perspectives. Here's the full quote: Optimization often involves making code less clear, more brittle, or with a more pasta-like organization. Frequently optimization requires writing code that if looked at out of context, doesn't make sense or might even look wrong. * I am arguing that these assumptions cannot be made so easily. Yes, they qualified the statements with "often" and "frequently", but the tone is clearly negative. It shouldn't be, and we shouldn't shun writing fast code out of the belief that it's at odds with readability or robustness.
- brightball 11y agoI've heard it in both contexts. When I first started getting into Rails I had to take over a project from a contract firm who very blatantly coded for "make it work" with no regard for the stress that certain things caused on the database. It was code that should have been a giant red flag to just about anybody, but was defended as "it would have been premature optimization". This was a piece of code that would, 1 one BEAUTIFUL line of Rails code...execute 50,000 queries on a single page. The problem is that when people hear that quote, without knowing it's original intended usage, they are able to use it as a "just get it done" excuse. This often happens when people are too shielded from what's going on in the database via an ORM layer like ActiveRecord for example. You don't need premature optimization...but you do need competent optimization. If you can see a blatant red flag that you're going to avoid by taking a little more time to do something a different way...do that.
- crdoconnor 11y ago>one BEAUTIFUL line of Rails code...execute 50,000 queries Something is off about that.
- brightball 11y agoIt was using an inline loop to execute operations on related data 3 associations over...before paginating.
- goldbrick 11y agoStill calling bullshit. You have to purposefully intend to get performance that bad in order to make ActiveRecord do the wrong thing that blatantly. The actual query execution is extremely lazy, that is, it doesn't execute the query until all the final chained method has been added to the planner.
- brightball 11y agoOh man, I wish I still had that code. These guys were militant "all logic in the objects" types so when they had to create a dashboard page, instead of just doing a scope with a couple of joins and the proper criteria; they went off of the base object, got the first set of associations, checked to see if it met the criteria by looping through the results and calling the object methods (which made associated calls to evaluate their comparisons under the hood) before finally converting the entire result set of about 20,000 objects into an array so that it could be sorted and the trimmed to exact number of records that were supposed to be displayed on that particular page. It was brutal. You would have thought it would require real, serious, effort to pull off that level of scary. I don't have the code to offer, but I can cite a couple of blog posts that I wrote about it a while back. It was so bad that I not only start blogging more because of it but I also taught a class to try to teach people both Rails AND PostgreSQL so they couldn't get into a situation of learning one without the other. Here's the posts... The Drawback to Web Frameworks (2013) - http://www.brightball.com/ruby/the-drawback-to-web-frameworks http://www.brightball.com/ruby/the-drawback-to-web-framework... "In order to look up what the status was on a particular object related to a user, they used some beautiful looking Rails code to find, filter, and combine results (and THEN paginate). The problem is that after Rails goes one level deep from a single record it starts performing single queries for each record in each relationship. That meant, for example, that in order to retrieve the most recent objects for a user who had over 18,000 in his account history that upwards of 50,000 queries were executed. The results of those 50,000 queries were then loaded into the web server's RAM (and SWAP), processed/sorted/filtered, and THEN paginated just to show the first 100 results. It was appalling and that is only one example." And here's the class that I taught to try to stop it from happening ever again. :-) http://www.brightball.com/classes/ruby-on-rails-and-postgresql-intro-to-advanced-in-3-weeks http://www.brightball.com/classes/ruby-on-rails-and-postgres...
- pbreit 11y agoAvoiding premature optimization most definitely is not an excuse to be sloppy or dumb.
- jlarocco 11y ago> Optimization often involves making code less clear, more brittle, or with a more pasta-like organization. Frequently optimization requires writing code that if looked at out of context, doesn't make sense or might even look wrong. I don't agree with that. It may be true for very low level micro-optimizations, but isn't usually the case for higher level optimizations that give the best performance improvements. A lot of times code can be sped up significantly just by using a different data structure or caching a value that's already computed somewhere else. For example, I've seen production C++ where the code was using a std::vector to keep a list of items in sorted order and remove duplicates. It was trivially converted to a std::set and saved several seconds of run time.