(Replying to PARENT post)
Knuth made his comment about optimization back when computing was about inner loops. Speed up the inner loop, and you're done. That's no longer the case. Today, operational performance problems seem to come from doing too much stuff, some of which may be unnecessary. Especially for web work. So today, the first big question is often "do we really need to do that?" Followed by, "if we really need to do that, do we need to make the user wait for it?" Or "do we need to do that stuff every time, or just some of the time?"
These are big-scale questions, not staring at FOR statements.
(Replying to PARENT post)
These days, things are often just not so in your face and a lot of "don't worry about it" advice. Which is often not bad advice in terms of getting things working. But eventually you do find you have to worry about it. Sometimes those worries happen far too late in bigger projects. So I think these Rules are pretty good. I'd also add in benchmarking very simple aspects of the toolset you are using to get an expectation of how fast things should be able to go. Often I have found (especially in the web world) someones expectation of how fast they think something can go is way too low because they have already performanced bloated their project and think its approximately normal.
(Replying to PARENT post)
If you want to run something like Windows 10 in a full-system emulator that is something like valgrind, performance matters. For each instruction emulated, you might need to run a few thousand instructions, and you can't get magical hardware that runs at 4 THz. Right from the start, you're deeply in the hole for performance.
Consider the problem of emulating a current-generation game console or smartphone. You can't give an inch on performance. You need to fight for performance every step of the way.
Just recently, I did a rewrite of an ARM emulator. It was all object-oriented nonsense. I haven't even gotten to profiling yet and the new code is 20x faster. Used well, C99 with typical compiler extensions can be mighty good.
It's important to have a feel for how the processor works, such as what might make it mispredict or otherwise stall. It's important to have a feel for what the compiler can do, though you need not know how it works inside. You can treat the compiler as a black box, but it must be a black box that you are familiar with the behavior of. When I write code, I commonly disassemble it to see what the compiler is doing. I get a good feel for what the compiler is capable of, even without knowing much about compiler internals.
(Replying to PARENT post)
Tempers his universals a bit.
In general, when working on web apps, which is mostly what I do, you don't gotta be quite that ambitious I think. On the other hand, you can't be _totally blind_ either, I've worked on some web apps that were disasters performance-wise.
But in general, while I gotta keep performance in mind all the time (okay you're right OP), I don't really gotta be _measuring_ all the time. The top 3% usually totally gets it.
But, when I worked on an ETL project -- performance performance performance all the way. Dealing with millions of records and some expensive transformations, the difference between an end-to-end taking 6 hours and taking 4 hours (or taking one hour! or less!) is _huge_ to how useful or frustrating the software is. And I had to start at the beginning thinking about how basic architectural choices (that would be hard to change later) effected performance -- or it would have been doomed from the start.
Certainly a game engine renderer is also more the latter.
But I don't know if you need _that_ level of performance focus on every project.
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
I'd like to refine the advice given a little bit, an approach I like to call "mature optimization". What you need to do ahead of time is primarily to make sure your code is optimizable, which is largely an architectural affair. If you've done that, you will be able to (a) identify bottlenecks and (b) do something about them when the time comes.
Coming back to the Knuth quote for a second, not only does he go on to stress the importance of optimizing that 3% when found, he also specifies that "We should forget about small efficiencies, say about 97% of the time". He is speaking specifically about micro-optimizations, those are the ones that we should delay.
In fact the entire paper Structured Programming with goto Statements[1] is an ode to optimization in general and micro-optimization in particular. Here is another quote from that same paper:
βThe conventional wisdom [..] calls for ignoring efficiency in the small; but I believe this is simply an overreaction [..] In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering."
That said, modern hardware is fast. Really fast. And the problems we try to solve with it tend towards the simple (JSON viewers come to mind). You can typically get away with layering several stupid things on top of each other, and the hardware will still bail you out. So most of the performance work I do for clients is removing 3 of the 6 layers of stupid things and they're good to go. It's rare that I have to go to the metal.
Anyway, if you're interested in this stuff, I've given talks[2] and written a book[3] about it.
[1] http://sbel.wisc.edu/Courses/ME964/Literature/knuthProgrammi...
[2] https://www.youtube.com/watch?v=kHG_zw75SjE&feature=youtu.be
[3] https://www.amazon.com/iOS-macOS-Performance-Tuning-Objectiv...
(Replying to PARENT post)
(Replying to PARENT post)
I've seen it given as an answer on StackOverflow, even when the question is not "should I optimize this?" but more like "is X faster than Y?"
We need to stop parroting these valuable, but not absolute mantras and use common sense.
(Replying to PARENT post)
- write for clarity with an architecture that doesn't greatly impede performance
- have good habits, always use datastructures that work well at both small and larger scales
whenever readily available (e.g. hash tables, preallocating if size is known)
- think longer about larger decisions (e.g. choice of datastore and schema, communication between major parts)
- have some plans in mind if performance becomes an issue (e.g. upgrade instance sizes, number of instances)
and be aware if you are currently at a limit where there isn't a quick throw money at the problem next level
- measure and rewrite code only as necessary taking every opportunity to share both
why and how with as many team members as feasible
(Replying to PARENT post)
I work on something that uses a lot of immutables with copy-modify operations. They never show up in a profiler as a hot spot. The most surprising hot spot was a default logger configuration setting that we didn't need. Other hot spots were file API calls that we didn't know we're slow.
I think what's more important is to use common sense in the beginning, and optimize for your budget. Meaning: Know how to use your libraries / apis, don't pick stupid patterns, and only do as much optimization as you have time for.
Sometimes an extra sever or shard is cheaper than an extra programmer, or gets you to market on time. Sometimes no one will notice that your operation takes an extra 20ms. Those are tradeoffs, and if you don't understand when to optimize for your budget, you'll either ship garbage or never ship at all.
(Replying to PARENT post)
I have also felt it would be a fun bingo game in a year to see when a famous quote of someone would come up. This Knuth quote would definitely be on there.
(Replying to PARENT post)
Most of those pages will bubble up when you do your first profiling session anyway.
You can get away with good data structures/good sql queries and a little big O analysis almost everywhere.
Premature optimization, premature nines of stability, premature architecture and abstraction are as evil as ever. They all distract you from moving forward and shipping.
Of course, if your product is BLAS library, database, compiler, web browser, operating system or AAA video game, that does not apply. I mean, for most of us "profile often" is a terrible advise.
(edit: spelling, clarifications)
(Replying to PARENT post)
The 10x dev is the dev that creates 10% the problems other devs create.
Thinking ahead is a skill the industry at large unfortunately seems to lack
(Replying to PARENT post)
There are also a lot of times when it doesnβt matter, possibly the majority of the time in some domains. Iβm working on a project now where the answer takes a couple of seconds to generate but it isnβt needed for minutes so spending time to make it faster would be a waste of my clients money.
(Replying to PARENT post)
Hrmm. In my experience very good programs also have very flat profiles. I donβt think a flat profile is indicative of bad performance culture.
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
1. Optimize only if needed.
2. Premature optimization is the root of all evil.
(Replying to PARENT post)
Good software is a multifaceted effort, and great software takes care of the important parts with attention to detail where relevant: great games libraries don't add significant overhead to frame time, great filesystem libraries don't increase read time, great security libraries don't expose users to common usage pitfalls creating less secure environments than had you used nothing at all.
It happens to be that optimization gets deprioritized at the expense of other things, where "other things" in this context is some category I fail to pin down because PMs don't give a shit about what that other category could be, and instead just care that whatever you're working on is shipped to begin with.
Great software developers will respect the important parts, and still ship. And yes, it's always easier to do this from the start than it is to figure it out later. Many things in life are this way.
I have a soft spot for performance, though, so I care about this message. One day hardware will reach spacial, thermal, and economic limits and when that day comes, software engineers will have to give a shit, because too many sure as hell don't seem to give a shit now.
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
(Replying to PARENT post)
They're two completely different schools of thought and may work well in either scenario. It depends a lot on your background, and your current context what way you are going to write code.
(Replying to PARENT post)
Totally true, and I have observed it IRL on large, old projects whose architecture was hostile to performance. And these products were doing computationally intense stuff.
> Performance is everyoneβs responsibility and it needs to be part of the process along the way.
Yes.
Everyone repeats "only optimize after profiling". It's true: if your program is running too slowly, you should always profile. But that rule only applies when your code is already slow. It doesn't actually say anything about the rest of the development process.
Developers should have a solid grasp of computer hardware, compilers, interpreters, operating systems, and architecture of high performance software. Obliviousness to these is the source of performance-hostile program designs. If you know these things, you will write better performing code without consciously thinking about it.
If this knowledge is weighed more heavily in the software dev community, people will put in the effort to learn it. It's not that complicated. If the average dev replaced half of their effort learning languages, libraries, and design patterns with effort learning these fundamentals, the field would be in a much better place.