Hacker News new | ask | show | jobs
by teki_one 1209 days ago
The thing that sets him off is that he is using a computer with enormous computing power and everything is slow.

He does have a narrow view, but it does not make his claims invalid.

I liked that his POC terminal made in anger made the Windows Terminal faster. But even in that context it was clear that by making some tradeoffs - which the Windows Terminal team can not make (99.99% of users do not run into the issue, but Windows has to support everything) - it could be even a lot faster.

So we live in a world where we cater for the many 1% use cases, which do not overlap, but slows down everyone.

Many gamedevs do their own tools, because they are fed up how slow iteration is. The same thing is happening at bigger companies, at some point productivity start to matter and off the shelf solutions start to fail.

6 comments

> The same thing is happening at bigger companies, at some point productivity start to matter and off the shelf solutions start to fail

This is perhaps the third time I've posted this on HN, but what you describe is the circle of life for widely-used software projects. Large tech companies are not immune to it, resulting in frequent component rewrites, deprecations and almost-drop-in replacements that shuffle complexity up or down the stack.

Step 1: Developer is fed up by how slow/bloated current incumbent is, so they write a fast, lean and mean project that solves their problems

Step 2: The project becomes popular on its merits, rakes in stars on Github as people discover how awesome it is

Step 3: Users start discovering limitations for their use cases, issues and pull requests pour in

Step 4: Thousands of PRs later, the project is usable by most people and has "won". It is now the incumbent, but no longer is as fast as it once was, but it also ships functionality catering to many niche needs

Step 5: Go to step 1

I've started a project that has the potential to go down this path but have a very strict 'implement your own diffs if you want them' for this particular project.

Like, feel free to fork away if you like. The core repository needs to be simple and stay true to its goals, and when it updates everyone downstream can update if they want to do that to themselves. But for what it is and does, maybe the project as it is is good enough.

I start feeling almost physically sick when I see the potential for bloat to creep into the software I write. This makes working with scaled software development with others particularly hard, however.

This is so true especially when it comes to frontend development also for backend framework but to a lesser extend.

But i also think that the product, library or framework owner should really box in its project and reject wild growth of features and prevent generalisation of the usage.

See Phoenix browser, now Mozilla Firefox.
Oh man Phoenix those were the days, 2003. I imagine a lot of HN readers here were only just born.
Don't forget Firebird!
Lynx on the C64 -- Is more nostalgia possible?
"But even in that context it was clear that by making some tradeoffs"

It was literally a weekend POC, and Casey Muratori even went beyond the POC part and fixed some emoji/foreign language bugs that were present in the Terminal.

Also, his intent was not to replace the Terminal. His intent was to demonstrate that it was possible to do the optimization in the way he suggested. Originally a Microsoft PM dismissed his suggestions and claimed it would be a "doctoral thesis project" or something.

All this "yeah it's a narrow view" is just moving the goalposts more and more. Not only he has to do a "doctoral thesis project" in a few days, he also has to completely replace a tool that's already written, bells and all? Where does it stop?

But how much of that slowness is due to code that values "cleanliness" excessively? I bet that if you look at the source of nearly any application on your PC, it will be very much not clean on average.
I think it would certainly value the kind of "clean" design patterns (or anti-patterns as I consider most of them) that object-oriented programming evangelists espouse.
Fine, but is that likely to be the cause of these applications generally being slow?
It wasn't about the tradeoffs that the Windows Terminal team "can not make" - it was about alternative optimizations and performance concerns that they arrogantly refused to consider as being possible, and which ought to have been considered if they were being properly competent.

Engineering tradeoffs are real. But hiding behind them every time when it can be pointed out that they don't actually apply - and when demonstrated with concrete evidence - is another thing altogether.

> The thing that sets him off is that he is using a computer with enormous computing power and everything is slow.

If that's his complaint, then "clean code" isn't the problem. The problem is capitalism and/or human nature.

Once something performs acceptably well, ie good enough to sell it, performance isn't going to get any better. Flashy stuff and features get you money, going from 400ms to 100ms gets you...nothing.

> going from 400ms to 100ms gets you...nothing.

According to Amazon [0] that'd be a 3% gain in sales (assuming the inverse holds true as getting slower, anyway).

[0] https://www.gigaspaces.com/blog/amazon-found-every-100ms-of-...

That's if it's in your sales flow, not if it's in your software.
Quite often the issue isn't 400ms vs 100ms, it's literally seconds vs single-digit ms.

> The problem is capitalism and/or human nature.

Fundamentally, yes.

> He does have a narrow view, but it does not make his claims invalid.

I would tend to disagree on this, specially when claims come from the gamedev world. Games are presented as finished pieces (even when they aren't), and not just a release milestone. Ideally, a game is a one-off effort where you write a piece of code and if you're lucky, you won't have to touch it again. So, doing one-off optimizations instead of focusing on milestones and long-term maintainability of the code is not only a possibility, but actively encouraged. That's why until rather recently (20 or so years), assembly optimization for critical execution paths, if not for most of the product.

Most of the rest of the software doesn't work like that. You often implement something that will be maintained, modified, extended and reiterated on for several years, not by you, but by several other teams with totally different experience and backgrounds. Or decades. Doing some fancy trick to skip a cleaner, extensible, maintainable design because you shaved off a couple of cycles on it is literally burning your employer's money and potentially causing huge issues in terms of maintainability, as many programs don't actually rely on a happy path like games do.

The main reason modern systems are slow isn't (just) because programmers are lazy - Its because most software - unlike games - have compatibility and maintainability requirements, and more often than not, a huge legacy support. And also, in these systems, most of development time is actually spent maintaining and extending existing code, not writing new one.

The author's assertion is fundamentally wrong, because software engineering is quite more than performance - even when it matters. Flashback to the beginning of the 90's, and "every game" used bresenham's algorithm to skip usage of the (slow or non-existent) div instruction. In some cases, a couple of bit wise shifts would also eliminate mul operations. These implementations were in some cases 2-4x faster than the classical counterparts, on a 12-40Mhz machine. Two cpu generations later, the Pentium comes out, and both mul and div take 1 clock cycle. The fancy pants implementation is now 3-5x slower at the same speed. Except now the cpu clock is 4x faster and shoveling around registers may actually impede parallel execution of code. All of this in a 5-year window. I envy the relatively stable instruction set of the last decade, where everything is sort-of predictable and assertions of speed can be made on code with a relatively high degree of confidence, but the reality is, silicon is cheap, and for most applications, performance is gained not by throwing away what makes some huge applications barely maintainable, but by deploying hardware. New, fancy, faster, cheaper and more economical hardware. Choosing a single metric (performance) and an instance in time to bitch about something is actually a disservice to the community at large.

> Two cpu generations later, the Pentium comes out, and both mul and div take 1 clock cycle.

Where are you getting this information? Agner[0] lists DIV as taking 17 cycles at best (8-bit operand already in a register) on the P5, and MUL as taking 11 cycles. Even Tiger Lake takes 6 cycles for DIV.

There are ways [1] to beat that, but I don't think you can get it down to a single cycle.

[0]: https://www.agner.org/optimize/instruction_tables.pdf p.162

[1]: https://lemire.me/blog/2019/02/08/faster-remainders-when-the...

You are completely right, I just had a major brain fart. I probably mixed up some things (or had some bad/incomplete source at the time). More than two decades have passed, so its probably me with wires crossed.
> “Ideally, a game is a one-off effort where you write a piece of code and if you're lucky, you won't have to touch it again.”

Ideally a game pulls in over a billion dollars per year, every year for over a decade. Think World of Warcraft or Fortnite, not Flappy Bird.

And the amount of money changes the fact that the core engines are written as a one-off effort how, exactly? Updates to the scripting engine to fix play-ability issues and content updates aren't really heavy software refactoring. Sure, there are usually some actual code bugfixes on the initial releases - and more often than not - related to someone implement some really clever trick that raises an exception on some cpu. Its not like they are incrementally rewriting and extending the internal engine for a decade, as it happens eg. with a browser.
If you think that, you're not familiar enough with modern games as a service. Fortnite lives on the latest version of Unreal Engine, and Unreal Engine changed a lot from the initial Fortnite development until now with many new features, rewritten parts, and major refactoring of other parts. It's huge and constantly evolving, so it is similar to, i.e., browsers.
"Games are presented as finished pieces" is an idea that's at least a decade out of date. The industry has gone very hard on the idea of Games as a Service and it's now normal for AAA games to receive years of content updates.
From a software perspective, they are. Most games don't change requirements (or base code) during their maintenance releases, as these releases may fix some code bugs, more often than not provide only incremental updates on content. Compare that with eg. intermediate releases of software like OpenOffice.