3 ms·
I like this article. It’s easy to forget what these classic CS papers were about, and I think that leads to poorly applying them today. Premature optimisation o
by dan-robertson 1y ago
I like this article. It’s easy to forget what these classic CS papers were about, and I think that leads to poorly applying them today. Premature optimisation of the kind of code discussed by the paper (counting instructions for some small loop) does indeed seem like a bad place to put optimisation efforts without a good reason, but I often see this premature optimisation quote used to:
- argue against thinking about any kind of design choice for performance reasons, eg the data structure decisions suggested in this article
- argue for a ‘fix it later’ approach to systems design. I think for lots of systems you have some ideas for how you would like them to perform, and you could, if you thought about it, often tell that some designs would never meet them, but instead you go ahead with some simple idea that handles the semantics without the performance only to discover that it is very hard to ‘optimise’ later.
- godelski 1y ago> a ‘fix it later’ approach Oh man, I hate how often this is used. Everyone knows there's nothing more permanent than a temporary fix lol. But what I think people don't realize is that this is exactly what tech debt is. You're moving fast but doing so makes you slow once we are no longer working in a very short timeline. That's because these issues compound. Not only do we repeat that same mistake, but we're building on top of shaky ground. So to go back and fix things ends up requiring far more effort than it would have taken to fix it early. Which by fixing early your efforts similarly compound, but this time benefiting you. I think a good example of this is when you see people rewrite a codebase. You'll see headlines like "by switching to rust we got a 500% improvement!" Most of that isn't rust, most of that is better algorithms and design. Of course, you can't always write your best code. There's practical constraints and no code can be perfect. But I think Knuth's advice still fits today, despite a very different audience. He was talking to people who were too obsessed with optimization while today were overly obsessed with quickly getting to some checkpoint. But the advice is the same "use a fucking profiler". That's how you find the balance and know what actually can be put off till later. It's the only way you can do this in an informed way. Yet, when was the last time you saw someone pull out a profiler? I'm betting the vast majority of HN users can't remember and I'd wager a good number never have
- sfn42 1y agoI completely agree with most of what you've said, but personally I rarely use a profiler. I don't need it, I just think about what I'm doing and design things to be fast. I consider the time complexity of the code I'm writing. I consider the amount of data I'm working with. I try to set up the database in a way that allows me to send efficient queries. I try to avoid fetching more data than I need. I try to avoid excessive processing. I realize this is a very personal preference and it obviously can't be applied to everyone. Someone with less understanding might find a profiler very useful and I think those people will learn the same things I'm talking about - as you find the slow code and learn how to make it fast you'll stop making the same mistakes. A profiler might be useful if I was specifically working to optimize some code, especially code I hadn't written myself. But for my daily work it's almost always good enough to keep performance in mind and design the system to be fast enough from the bottom up. Most code doesn't have to be anywhere near optimal, it just has to be reasonably fast so that users don't have to sit and stare at loading spinners for seconds at a time. Some times that's unavoidable, some times you're crunching huge amounts of data or something like that. But most of the time, slow systems are slow because the people who designed and implemented them didn't understand what they were doing.
- sgarland 1y agoIFF you understand computing fundamentals, and IFF you have a solid understanding of DS&A, then yes, this is a reasonable approach. At that point, a profiler will likely show you the last 1% of optimizations you could make. Most web devs I’ve met do not meet that criteria, but sadly also have rarely used a profiler. They’re not opposed to doing so, they’ve just never been asked to do so.
- godelski 1y agoI think you're missing "IFF you write all the code and use no libraries." The strategy works well, as you point out, for a single person but doesn't scale and can't be applied to library code without doing a deep dive into the library. Which at that point, a profiler is far more time effective. > They’re not opposed to doing so, they’ve just never been asked to do so. I think the best option is to integrate profiling into the CI framework. Like a git pre-hook or even better, offload so that your VMs profile while you're testing different environments. I think mostly it is a matter of habit. I mean let's be honest, we probably don't care about profiling our for fun project codes. Where profiling really matters is in production. But I think the best way to normalize it is just to automate it. Which, honestly, I've never seen done and I'm really not sure why.
- naniwaduni 1y ago> It’s easy to forget what these classic CS papers were about, and I think that leads to poorly applying them today. Notably, pretty much the entire body of discourse around structured programming is totally lost on modern programmers failing to even imagine the contrasts.
- runevault 1y agoIt is interesting that there's so much discourse about the effort people have had to put into data structure and algorithm stuff for interviews, but then people refuse to take advantage of the knowledge studying that gives you towards trivial effort optimizations (aka your code can look pretty similar, just using a different data structure under the hood for example).
- sfn42 1y agoThat's because people don't get it. You see people saying things like "It's pointless to memorize these algorithms I'll never use" - you're not supposed to memorize the specific algorithms. You're supposed to study them and learn from them, understand what makes them faster than the others and then be able to apply that understanding to your own custom algorithms that you're writing every day.
- IshKebab 1y agoI 100% agree. I could have written the same comment. The biggest way I see this is picking an architecture or programming language (cough Python) that is inherently slow. "We'll worry about performance later" they say, or frequently "it's not performance critical". Cut to two years later, you have 200k lines of Python that spends 20 minutes loading a 10GB JSON file.
- dan-robertson 1y agoI failed to put an important point on the above comment, which is spending too much time designing the perfect thing can lead to a system that is either never finished, or one that meets the goals but doesn’t do the work it was originally intended to do, and then it’s too late to pivot to doing the right thing. If you develop in an environment where you have high velocity (eg python) you can much sooner learn that you are building the wrong thing and iterate. Most systems do not have very high performance requirements. A typical python web application is not going to need to service many requests and the slow stuff it does is likely going to be waiting on responses from a database or other system. The thing to make such a program faster is to send better db queries rather than optimising the O(1 web page) work that is done in python.
- sgarland 1y agoI know this was an example, but if you get to that point and haven’t swapped out Python’s stdlib json library for orjson or some other performance-oriented library, that’s on you.
- IshKebab 1y agoThat's exactly the sort of after-the-fact performance workaround that you should avoid. Instead of using a faster JSON parser, you shouldn't have used JSON in the first place.
- Joker_vD 1y agoYou also need to remember that back when those classic CS papers were written, the CPU/RAM speed ratios were entirely different from what they are today. Take, for instance, a Honeywell 316 from 1969 [0]: "Memory cycle time is 1.6 microseconds; an integer register-to-register "add" instruction takes 3.2 microseconds". Yep, back in those days, memory fetches could be twice as fast as the most simple arithmetic instruction. Nowadays, even the L1 fetch is 4 times as slow as addition (which takes a single cycle). No wonder the classical complexity analysis of algorithms generally took memory access to be instantaneous: because it, essentially, was instantaneous. [0] https://en.wikipedia.org/wiki/Honeywell_316#Hardware_description https://en.wikipedia.org/wiki/Honeywell_316#Hardware_descrip...