12 ms·
The Fallacy of Premature Optimization (2009)
- valand 7y agoThis is a reup of https://news.ycombinator.com/item?id=13505721 https://news.ycombinator.com/item?id=13505721 I think that this is important to be shared once in a while
- mewpmewp2 7y agoPeople seem to always talk in absolutes, black and whites, concerning this topic. In my experience most engineers take a situational approach. Sometimes it is worth it to optimize early, sometimes it is not. Some things are worth optimizing, some not. Also some things are worth optimizing to certain level. These types of articles and claims conjure up a debate because everyone is imagining a different scenario in their heads. It is entirely plausible that each claim could be the best solution in a different scenario. Do these articles assume that engineers are incapable of thinking flexibly and need to follow some absolute truths that have to be debated? Have I been around too good engineers that I have not noticed this issue?
- simion314 7y ago>Do these articles assume that engineers are incapable of thinking flexible There are some developers that are like that, they read in a book about some patterns or idea and then in code reviews will jump on you because you did X wrong and not followed his bellowed pattern from the book.
- tmcb 7y agoI read somewhere else yesterday that “it’s easier to throw hardware at a problem than people.” It certainly does not hold true for all cases, but turning this aphorism into a question seems to give us some good heuristics---provided you do know the what the root cause of your performance issues could be, of course.
- Laakeri 7y agoIt's easy to throw hardware at a problem that can be parallelized efficiently. It's very hard to throw hardware at inherently sequential solution.
- astrobe_ 7y agoIt is also a bit less easy to throw hardware at a problem when your software is actually embedded firmware. Upgrading or adding hardware reduces your profit per unit. But TBH in this particular field Moore's law still rules. Sometimes you are forced to upgrade to a better component for the same price because the component you chose five years ago has reached end-of-life. Yet paying attention about optimization allows you to do more with what you have, or sometimes allows you to use less optimal but more convenient or simpler approaches.
- TeMPOraL 7y agoIt was easy to throw hardware at a sequential problem, a decade ago. CPUs were still improving their single-core performance year after year, and memory access and all kinds of IO devices kept getting faster and better. I'm guessing that time was where this idea originates from. Today, things are different. Single-threaded performance isn't going to be improving much in foreseeable future; the effort shifted to improving parallel performance and, more recently, power consumption. So if you write slow code - perhaps by choosing a slow software stack - your code will remain slow.
- sharpneli 7y agoIn cases where you control the hardware and the problem is sufficiently parallelizable. If you are releasing consumer applications either your program works smoothly on the device a consumer has or not, let alone has the ability to buy either financially or fundamentally (as in you don’t find a phone with desktop level performance anywhere, because they don’t simply exist).
- tmcb 7y agoThis is partly what I was trying to convey with the "turning this aphorism into a question" fragment. Sometimes it is just not possible, or it is too expensive, to increase hardware performance. Premature optimization, or at least one of its manifestations, is failing to consider the opposite.
- post_below 7y agoI think maybe yes, you've been around mostly good engineers. It's not a problem that's exclusive to coding, you find people talking loudly about absolutes in most fields. People like definitive answers. Makes us feel secure. Which makes absolutes easy to sell, and especially popular with people who feel out of their depth. It also makes them popular in academics. You also find flexible, creative thinkers in the same fields. They're just not as loud, or as numerous, in my experience.
- cgriswald 7y agoAbsolutes can be indispensable when learning. An entire concept can be boiled down to black-and-white, and often can be completely forgotten about while a learner groks the rest of a subject. Part of the path to expertise for a learner is to go back and challenge those absolutes, because those absolutes are now part of the learner's assumptions. When people espouse absolutes, I generally (not absolutely) assume either they're not experts or they think their audience can't handle nuance.
- valand 7y ago> Do these articles assume that engineers are incapable of thinking flexibly and need to follow some absolute truths that have to be debated? I think this article assumes that there are possibly engineers that don't think flexibly and need to follow some "absolute truths". > Have I been around too good engineers that I have not noticed this issue? Probably. I mean, I would love to be between your colleagues. In some places, submission to ideas rumored to be proven is valued more than flexible thinking, critical thinking at any time, etc. I know that some countries in Asian have a rather high degree of culture like this. It doesn't apply to everyone.
- teddyuk 7y agoI just finished a project where literally everything had been over engineered to the point that it took them weeks to do a release. The code generally had one path but every method was built using dictionaries of possible classes that would implement interfaces so they wouldn’t have any duplicate code. Sometimes some dev teams go down the wrong path.
- MaxBarraclough 7y ago> dictionaries of possible classes Sounds like a horror show built by people who don't understand OOP.
- Doxin 7y agoSounds like a group of people succumbing to the inner platform effect: https://en.wikipedia.org/wiki/Inner-platform_effect https://en.wikipedia.org/wiki/Inner-platform_effect It's not nearly as uncommon as I'd like.
- MaxBarraclough 7y agoIt doesn't sound like inner-platform-effect to me. teddyuk didn't say they were reinventing the wheel, just that they were doing awful things with dictionaries.
- teddyuk 7y agoI started reading the article: “ The inner-platform effect is the tendency of software architects to create a system so customizable...” Yup, that was it and I have seen it so many times - architects should think that a flexible system that “can just” handle any possible future requirement. This always ends in a mess of junk that isn’t actually needed by the business.
- FpUser 7y agoThey might as well hand a development tool to a client and call it a day ;) Super flexible
- gnulinux 7y agoSpeculation time (not a linguist): I think this is an inherent problem in human languages, they're fundamentally not sophisticated enough to communicate nuances. We see this all the time in engineering, politics etc. People always talk in terms of rules because these are easier to phrase, but in reality everyone takes every decision situation-by-situation basis. But then when you need to explain these nuances, you simply need to use more words. I think this also makes sense. Take a cat. Cats clearly are able to think a lot more complex than they can communicate. They use a set of very basic body cues to communicate, but they are able to process information a lot more complex than these. Why would this not be like this humans too? I have some very opinionated friends on coding styles, libraries, programming languages, programming "rules", "principles" etc... They're all sort of rubbish. I think it's important to know and study them because they give you different ways to think of engineering. But when it's time to commit code to production does anyone really think about "ah this is not DRY, premature optimization, NIH etc...". I claim no. We always think about the specific situation. Is it good to invent this code. Is it good to optimize this possible future extension. Is it good to repeat this particular code. We all know repeating code is "bad" but we all also know reasonable exceptions. So yes, all rules are by nature fuzzy. In fact, whenever someone tells me a principle they hold, I immediately start thinking about fuzzy-fying it i.e. thinking of possible niche cases where this principle would reasonably NOT hold.
- SolaceQuantum 7y agoIMO part of this is that nuanced processing is actually a very expensive operation and people would be unable to function without some level of abstraction- language as in all things. That's why, for example, Jeff Vandermeer writes in his Wonderbook that each author has a "thorn", something that bugs them and compels them to write and explore infinite nuances of the topic of their focus.
- jdashg 7y agoI think it's systemic, not really linguistic. Complexities are fractal, and there's fundamentally no way to succinctly express them in a title or summary.
- no-s 7y agoPeople seem to always talk in absolutes, black and whites, concerning this topic. Maybe this is just my cynical perception, but I often hear people try to justify situational bad practice by citing outliers unrelated to the situation at hand, particularly with optimization. As you say, they usually imagine a different scenario is at hand. For those situations I quote HL Mencken: Explanations exist; they have existed for all time; there is always a well-known solution to every human problem—neat, plausible, and wrong. I interpret the premature optimization dictum to mean: Really the only time to talk about optimization at the early stage of a project is to set performance objectives or when the project is about optimization. Otherwise people should seek relatively optimal solutions which optimize efficiency at delivery. Optimization starts when they have running code that doesn't meet performance goals. Other optimization is premature, in one sense or another.
- candiodari 7y agoSo recently John Carmack posted: https://twitter.com/ID_AA_Carmack/status/1210997702152069120 https://twitter.com/ID_AA_Carmack/status/1210997702152069120 "My formative memory of Python was when the Quake Live team used it for the back end work, and we wound up having serious performance problems with a few million users. My bias is that a lot (not all!) of complex “scalable” systems can be done with a simple, single C++ server." And so a lot of people seem to feel the need to once again bring back all the discussion in absolutes of optimisation being useless, or the only thing that matters. I've found the same as John Carmack btw. Taking some component of a customer system, translating it to C++, can make a system that needed 10+ servers suddenly run a lot faster on a single server (meaning higher throughput AND lower latency, because in addition to the raw speed advantage of C++ there's so much you can do in C++ that's not really feasible in, say Python. For example, mmapping files). But C++ is not exactly the first thing I reach for when something new springs to mind, or I want some data analysis done, or ... (even though C++ is excellent for running production data analysis jobs)
- andy_ppp 7y agoPython is probably the wrong tool for this though, that doesn’t make it bad. Writing this in erlang, elixir or scala or even Golang would be a better choice. That’s not premature optimisation, that’s understanding what problems are requirements up front. Choosing most of these when you have zero users is probably wrong; python might be better as with its libraries it could get you to market faster!
- deleted 7y ago[deleted]
- valand 7y agoIt came to a full circle, lol. I reposted this article because of that tweet. > But C++ is not exactly the first thing I reach for when something new springs to mind, or I want some data analysis done, or ... (even though C++ is excellent for running production data analysis jobs) Me too. C++ is a pain in the ass (although I only touch that thing in my college day building simple A* AI). I always go to seeking libs in TS (my go-to language) or at least JS before consulting to other languages. > I've found the same as John Carmack btw. Taking some component of a customer system, translating it to C++, can make a system that needed 10+ servers suddenly run a lot faster on a single server (meaning higher throughput AND lower latency, because in addition to the raw speed advantage of C++ there's so much you can do in C++ that's not really feasible in, say Python. For example, mmapping files) I think it's just the nature of true compiled language that comes with a very minimum runtime. Multi steps compilation in Java and interpretation in JS or Python always need sacrifice. I have seen great devops engineers pulling hairs over kubernetes configuration issue happening just because a Java spring boot service needs an enormous memory just to initialize some runtime objects. > And so a lot of people seem to feel the need to once again bring back all the discussion in absolutes of optimisation being useless, or the only thing that matters. And then, I found Rust, which is a pretty nice language. It bridges that memory safety VS optimisation issue. Although the learning curve is pretty heavy on the syntax and the new paradigm it brought, it's pretty easy for me who is used to code in TypeScript. I'm just surprised at the minimum mention of Rust in that tweet.
- londons_explore 7y agoWhen starting a project, I prefer to have a "performance budget'. For example "The application must start in under one second". Then during development you can divide up the budget - 400 milliseconds for loading dependencies, 200 milliseconds for rendering the UI, etc. Then you can decide if any given optimization is needed or necessary to meet your goals.
- londons_explore 7y agoMy latest project has a performance budget of (on average) 150 milliseconds per click, and it's a web-app. It's going to be a tough goal to meet, considering typical web apps today take 5000ms to load!
- touisteur 7y agoThat's what's often done in mission-critical software with critical latency elements. Problem is, you have to make sure those values are directly traced to either specific customer requirements, whole system spec or normative reference. It's too easy for systems engineers to come up with hard-to-reach numbers with no grounding on the Real customer need... You also have to specify and measure exactly the correct element. Sometimes the latency budget is split in not clearly-cut parts, and on events or categories of events that are not clearly defined. Saying 'all requests should give a complete result in < 20ms' just isn't realistic and creates a world of hurt. What kind of request? Always, always? In what load conditions? What about error conditions? Fail-over conditions? Hot/cold start?... It's not simple like specifying a clear-cut feature. Performance budget should often not be all black and white. Especially when trying to push the envelope of what modern PC hardware (with OoO execution, complex memory hierarchies, multicore CPU/GPU rapid-busy-bused hybrid archs) can do. It should probably be a risk law, and at least a critical spec, and thoroughly tested and regression-tested as such. And here, sometimes premature optimization will be necessary. If someone gives you hard latency requirements, you'll have to say, very quick, 'I'll need a soft/hard real-time OS it won't do extreme high-throughput'. You'll have to bench... Premature /micro/-optimization is a problem, sure. Make it work, make it right, make it fast. But global optimization must start at the system design level. How much money do you have? What can you do for $X?
- Nursie 7y agoPremature optimisation, to me, is spending days working out a new algorithm for 5% saving on something that looks inefficient to you but you haven't actually any idea if it's really a problem. I've never met any of these engineers who think optimization is always wrong.
- mehrdadn 7y agoTo you premature optimization means spending days eking out 5%, but that's not how everyone sees it. Lots of people I've seen would also call e.g. spending 1 hour vs. 30 minutes on a solution that'd be (say) >= 3x faster "premature optimization" due to the fundamental design decisions (not micro-optimization).
- rightbyte 7y agoDogmas are a poison to programming. "No gotos" "You aint gonna need it" "No benefit for the customer" And of course, the topic of this link.
- ahartmetz 7y agoYes. Experts (and salespeople, when asked for a price) know that the answer to almost everything is "it depends" ;)
- Nursie 7y ago> Lots of people I've seen would also call e.g. spending 1 hour vs. 30 minutes on a solution that'd be (say) >= 3x faster "premature optimization" due to the fundamental design decisions (not micro-optimization). And it still might be that way, if the piece you're optimizing isn't performance critical at all, and the effort might be better spent elsewhere. But it might not. The whole thing is a grey area and a good software developer learns to spot when they're spending time on something that doesn't need this effort right now.
- dr_j_ 7y agoBrilliant article. I am currently implementing a programming language and have had to think very hard about representation (in particular). I would highly recommend this for any serious programmer wanting to learn a bit more about performance.
- cjfd 7y agoHow much optimization you need depends on the situation. The first question is for how many concurrent users are you going to write it for. In most cases O(n^2) is too much unless you know that in practice n is always going to be less than 10. Even then you should be quite certain that n is never going to become bigger, which you very often aren't. Removing constant factors, i.e., turning 3*n into n, should only be done if it is not difficult and is not bad for code quality in most cases. But at some point you should start removing these constant factors. Maybe if you need to handle more than 10000 requests a second. These numbers are highly variable depending on the application, the language and the use.
- wruza 7y agoUpvoted you for the first half. Hell, if algo is cubic or exponential out of pure simplicity, then as little as x3-10 input will bring it to its knees. It is not worth revisiting it later with all surrounding costs, if that’s inevitable anyway. Optimization is premature only if the code is not already fantastically stupid, which may happen too often irl to ignore that. Couldn’t agree with constant factors though. These are pretty random, n-independent (i.e. scalable) and the net expense of making code less obvious is usually bigger than throwing more/better hardware at it, but ymmw.
- saagarjha 7y agoRunning a single pass instead of two is often useful.
- samatman 7y agoThis falls apart when you consider one common scenario: We are loading a number of data files and the source of truth is remote. This is O(n) the amount of data. Two ways to do it: always request the remote data, or cache it, and only ask the remote for changes. These differ by a constant factor, and it's always a good idea to maintain a local cache when it's possible. Otherwise there's a very good chance that startup time will be dominated by network requests.
- 7y ago
- loopz 7y agoWikipedia has the quotes: https://en.wikipedia.org/wiki/Program_optimization#When_to_optimize https://en.wikipedia.org/wiki/Program_optimization#When_to_o... We shouldn't reinvent a phrase. Premature optimization has always been about programming efficiently, ie. a newbie programmer or even expert "elite" programmer could easily fall into the trap of optimizing prematurely. That means: Spending too much time on very little gain performance-wise, thinking it's important to eke out every little drop of performance. It's a programming lesson only. Experience even show that premature unproven tweaks can both reduce performance and make code harder to read and maintain. Then there's the business lesson: Since for the last decades we've had Moore's Law and then more, it's been very hard to make the effort pay off by programming for performance. So businesses have learnt to focus on reducing programming time. Coincidentally, it's been shown that quick lead times are beneficial in the competitive marketplace as well. This is a business lesson (not about the programming phrase "premature optimization"!). We're seeing a reintroduction of optimization and performance, because meeting a ceiling in CPU cycles and the need to utilize more cores efficiently. So we have Golang, Rust, WebAssembly, etc. Having a snappy website and not annoy your users will pay off as well (hello there multiple choice agreement-notices!). But the programming lesson still stands: For many types of workloads, it doesn't make sense to spend too much time optimizing, performance wise, unless you see proven benefit outweighing the costs. In most cases, it's actually better to optimize afterwards (ie. prototyping and iterating), unless one has a specific algorithm or solution in mind beforehand. The business lesson is similar, with the added twist of being a criteria wether you make it or break it. For programming, you could just do it for fun or a hobby, and can premature optimize to your hearts content if you like. But it'll be harder now to fall into that trap instead of making something more worthwhile! ;-)
- dana321 7y agoPremature Optimization can hold back the release of software, and make it more complicated to debug. . Say you already have a function that returns the list of children in a node.. . But you need a function that brings back only the first child if it exists. . 1. Do you copy the function and return just the first item when you have it (with the associated code around the function) for efficiency sake. 2. Or.. Call the existing function and return the first item if there is at least one element? . 1 Will be the best answer if you have a million records to load from disk. 2.Will be the best answer if you only have 20-30 records on average. . But 2 is the best answer before debugging, check that the code works properly before duplicating it and modifying it. Answer 3 would be to add a limit parameter, and call the other two functions with it. That way, if limit=0, return all records. if limit=1, return one record maximum. . Sometimes the answer is to think differently about the problem altogether.
- unlinked_dll 7y agoTo be pedantic, the answer is neither. You use an abstraction that supports either answer with similar ease, provided by the language/framework/tools you used. You bring up a very real point, but the most obvious cases are also most obvious to the people developing the stack below you and have almost certainly gone through the trouble of solving those problems. This issue rears its head when edge cases are non-obvious and typically manifest through profiling, not through design meetings.
- chrisweekly 7y agoOne thing I haven't seen in the comments yet is the simple observation that premature optimization is, by definition, a mistake -- otherwise it'd merely be "optimization". The real question is, what makes it "premature"? I think Knuth (in his famous "... root of all evil" quote) was referring specifically to programming, and to spending time on optimizations prior to functional completion. The mantra, "First make it. Then make it work. Then make it better." [or similar] holds water. But it's pointless to debate in general terms what precisely constitutes a "premature" optimization, vs a merely timely one, or adherence to best practices, given the infinite combinations of circumstance and context relating to software development projects.
- username90 7y ago> "First make it. Then make it work. Then make it better." That only works when you do simple things, for harder things the "make it better" part usually requires a complete rewrite if you didn't properly think things through from the beginning. A better mantra would be "First make it, then make it again, then make the real version".
- eloisant 7y agoThe real learning here is that "premature optimization" is a thing, you shouldn't optimize right away.
- amelius 7y ago> The mantra, "First make it. Then make it work. Then make it better." On HN we would say: first make it, then sell it, then make it work, and finally, make it better :)
- chrisbennet 7y agoIf optimization is going to be a concern, the thoughtful choice of the algorithm(s) up front is not "premature". Currently, I'm working on a project with a ring buffer (a kind of FIFO buffer). It isn't fast (not lockless) but has a well defined interface so I can swap it for fast one later if I need to.
- tylerjwilk00 7y agoFor some parts of a system if you write it correctly the first time there will be no need for optimization, premature or otherwise. If you know you will need to cache something just cache it, it's not premature, it's best practices. Exercise the Pareto principal during development and the areas that truly need optimized will present themselves in time.
- deleted 7y ago[deleted]
- kerkeslager 7y agoThis article is terrible, just full of straw man arguments and holier-than-thou attitude. Meanwhile, the article completely fails to present any data, completely fails to identify why organizations fail to optimize, and completely fails to provide any solutions. The article basically just pretends there's some large anti-optimization movement so he can knock it down. And even while proving the obvious (that optimization is important), the article uses appeals to authority rather than actual data. Ugh. > Today, it is not at all uncommon for software engineers to extend this maxim to "you should never optimize your code!" Funny, you don't hear too many computer application users making such statements. Funny, you don't hear too many computer application users asking for optimization, either. The rare, high-profile cases where people complain that something is slow get a lot of attention, but the majority of the time, the feedback you get from users is a resounding silence. I wish users would give me unsolicited actionable feedback on my software, but the reality is, it takes effort to get feedback, and usually people don't complain about performance, they just have a general feeling of malaise about the software that doesn't rise to the level of an explicit complaint. In 11 years of software development, I've had only a handful of users ever complain about performance. The times I've optimized are almost always a result of performance logging. Performance logging lets me say to stakeholders, "This DB query is taking a full second, and 30% of users are exiting the application on that screen--can I spend time to optimize this?" Funny, you don't actually hear too many software engineers actually saying "you should never optimize your code", either. I stopped reading at the "observations" section, which were just too full of cringe. I skimmed the rest, though, and noticed that the author's suggests a few books on assembly language. Good call, guy, I'll be sure to tie my application to a specific processor architecture so I can make it extra difficult to understand why memory is getting thrashed or thread switches are happening at such inopportune times.
- ncmncm 7y agoThis article is more current than when it was written. We are deep into the Post-Moore's Law era, where a new generation gives, now, 120% rather than 200% of the previous generation's performance. Next generation we might get 115% of this, or 110%. Another consequence is that the improvements we get have become dodgier and less reliable, so that tiny, irrelevant-looking changes in the code may mean a 2x speedup, but more commonly a 2x slowdown. (This is in no way an exaggeration.) The bargain we get from pervasive penetration of more kinds of caches is that sometimes our programs are faster, but we no longer know how fast they should be, or whether another factor of two or ten has been left on the table. Sorting algorithms are quite mature now, so that a 20% improvement in a relevant case is important, yet a factor of 2 or more may come from the compiler choosing one instruction over another. Compiler regression bug reports now routinely complain of a 2x performance loss from that instruction choice, but fixing them would result in 2x losses in some other set of programs, instead. We get new unportable compiler intrinsics to patch the failure, that often don't, for obscure reasons.
- BubRoss 7y agoMoore's law was always about transistor density increases, not performance, and definitely not about serial performance in a single core, no matter how much people want to reframe it. Transistor density is still improving, just not as quickly and CPU speed is still increasing, just not on a single core.
- ncmncm 7y agoNot so. Earlier generations came with higher, often doubled clock speeds. Many programmers today have never seen such a doubling, yet policies still assume them.
- BubRoss 7y agoClock speeds have nothing to do with Moore's law, which was about transistor density. I'm not sure how you can say that a doubling in density hasn't happened when there are "7nm" 64 core CPUs out there. Transistor density has slowed but not stopped. Moore also predicted an exponential increase in price for density improvements which has also seemed to happen.
- BubRoss 7y agoI think a lot of programmers still don't realize that this idiom comes from doing micro optimizations early. Software does need to be architected for performance up front. If you aren't able to work on data with a lot of locality or have latency between fundamental operations, you won't get fast software until you address these issues. If you are really starting from scratch you will barely understand the problem, but once you do, you can make sure your architecture will align with what you are doing. After that, optimization becomes much lower hanging fruit.
- mattxxx 7y agoI've never heard anyone actually say that optimization is evil... probably, because people seem to actually enjoy optimizing code. What's "evil" is optimizing without benchmarks/profiles/etc. Naive implementations are usually easier to write, and can give you a baseline for how much there is to gain (as well as providing "correct examples" for more complicated algorithms).
- JoeAltmaier 7y agoOn a modern full-sized laptop etc, sure code efficiency doesn't matter much. But in anything smaller e.g. embedded device, radio card, cheap phone, it means the world. The difference between a product and a fail. Embedded programmers can probably be identified by their insistence on code efficiency. Speed, space, storage, all critical to them.
- FpUser 7y ago"On a modern full-sized laptop etc, sure code efficiency doesn't matter much" Well it really mattered to me when I lost my patience and replaced a piece of code written in Python that was doing some data manipulation/processing with the native one. Suddenly what used to take an hour got down to less then 1 minute.
- JoeAltmaier 7y agoYeah big data can always beat the cpu. For apps, not so important I guess.
- FpUser 7y agoI have made quite a few enterprise grade desktop apps. They'd normally involve device control, real time data processing, graphics multimedia etc all running in many threads communicating using my own internal publish-subscribe and in memory EAV database. For each one performance mattered a great deal. Yes I understand it may not matter much for many database front end apps but the world does not end on those.
- JoeAltmaier 7y agoWell you're a saint. The average desktop app repaints with stuttering, hangs for seconds, and has all modal controls. So few care about these things any more. Is 'performance' the right word for this? Its more like user experience or latency - the controls/graphics should be run on a different thread than the data processing.
- honkycat 7y agoMy team at work is extremely guilty of this, and half the time they aren't even correct. I have coined the term "voodoo optimization" in response to a point Martin Fowler made in his book "Refactoring 2nd Edition": When running Javascript, for example, you are working with a compiler and engine that has had thousands of man-hours and millions of dollars invested into it. The compiler is throwing away variable declarations. It's merging for-loops. What you put in is not what comes out. You need concrete numbers and FACTS to optimize your code. Deciding "this looks slow" is not an effective optimization method.