Hacker News new | ask | show | jobs
by svdree 3564 days ago
What you'll often find however, is that in the last step ("make it fast") you have limited room to maneuver, because of the stuff you did in the first 2 steps. If you really need high performance, you need to design for high performance, not just leave it as an afterthought.
4 comments

Usually it's almost impossible to predict where your design flaws would be until you actually use the thing in production. Because you make a lot of assumptions and some of them will inevitably be false. So, make it fast is mostly about changing design.
absolutely agree with your last sentence. But thats not a majority of software written in my experience.

  "If you really need *high performance*, you need to design for high performance, not just leave it as an afterthought." 
Emphasis, mine.
Then why do I encounter slow software every day? Why do we keep encouraging this?
Because this entire Mantra is horrible advice. All 3 need to be in the spec, and all 3 need to be coded for.
"Make it fast" sometimes does not need to be coded for if the applications is fast enough after the "Make it right" step.
Doesn't matter, every app has some speed requirement.. if it is trivial, then there isn't much to do for it.

It's not something you can just do later, because thats not how software works. Fast code needs designed to be fast. Not "fixed" at the end.

Because they stopped at step one (make it work) or two (make it right). Or the first of my three (borrowed from Joe Armstrong), make it work, make it beautiful.

It's not simply that they failed to plan for performance, it's that after making it work -they never measured and removed obvious bottlenecks-.

Most pieces of software don't need high performance. Drawing some widgets on screen just isn't that demanding. But it -does- require you to go back afterwards and remove places you introduced inefficiencies. You don't need to code in C and optimize against cache misses for that; you just need to take time after things work to make them not suck, and thats something a lot of software development doesn't take the time to do.

Most client software doesn't need performance. Drawing widgets is a client-side thing. Scaling is really the hot point that discovers bottlenecks. Server have to scale. And nobody has time to plan/code very far for scaling when they haven't succeeded yet.

I think its perfectly normal to write slow, non-scalable code as proof of concept. Then continue to attack bottlenecks as you grow (if you grow). Its a lucky startup that has to deal with performance. They can afford to dedicate a couple smart developers just to that issue.

Michael Dell said every time your company doubles in size, you have to reinvent your processes. True for software too.

Yeah, I just gave a random example of something that is very common in a generic software application; at some point, you draw some basic GUIs. Those can lead to performance bottlenecks as well (loading and displaying 10 data points in your test bed; easy. Loading and displaying 1 million data points in a production situation, a little harder). There's also basic network operations, some DB/disk writes, actual CPU usage for whatever processing has to occur, etc. Any of those may need to be super performant for some apps, some will be front end, some backend, but for many applications and uses, at least initially, it's not worth worrying about at first.

That said, I'd draw a distinction between vertical scaling and horizontal scaling. The former you should address as needed, as the gains are comparatively limited, and the bottlenecks are unknown (you think you're CPU bound; whoops, nope, I/O. Or whatever); the latter should be designed for if there's a chance you'll need it. Because oftentimes, things that are merely decisions early on (no difference in amount of work) can lead to savings of months of effort and churn down the line if you go for something that scales. Decisions like deciding what data needs to have strong consistency, versus what data can be eventually consistent (and choosing data stores based on that), trying to avoid shared state, thinking about "what happens if there are more than one of these?" and designing/implementing with that in mind (even if some aspects are super hard and you punt on them, there's plenty of low hanging fruit that you can address with minimal effort early, rather than massive later on).

Because there is no user story for "make it performant", and there is little thought put into dynamic design vs static design. If money comes in with crappy performance and it is hard to predict how much more money will come if the developer improved performance, then it won't be a business priority.
I've seen more performance problems caused by people not having clean code than I ever have from people not thinking about performance from the get go.

I've also seen plenty of performance issues ironically caused by performance hacks wedged in early on.

You will often find clean code and fast code converge on very similar places. It is often a false dichotomy to think code needs to be either clean OR fast.

Now this does break down, if you need to get to the point where you are bit twiddling, it is not going to be clean as using something higher level.. but you can often put the nasty parts in a static method somewhere and still have the code be very easy to read.

this reminds me of the post about the jvm code cache a few days ago where if they had left the jvm to optimize the code cache by itself, the would not have ended up with the problem situation where the had to spend time to figure it out their optimization was the cause of the problem.

-- sorry for the run on sentence.

Sure; but a working version is still really really useful to compare against (e.g. build up a suite of test cases) even if you have to redesign large parts for performance later.