Live data from Hacker News

“Clean” code, horrible performance

computerenhance.com

571–580 of 932 posts

Re: “Clean” code, horrible performance

#571

Earlier quoted context omitted.

Indeed. If anything this demo shows how badly C++ polymorphism performs. It doesn't necessarly means that all OOP languages created equal. Although I have no data to prove anything, and frankly don't care b/c all these arguments about clean vs dirty code are meaningless in an absence of formally defined rules and metrics universally enforced by some authority that can revoke your sw dev license or something like that

> It doesn't necessarly means that all OOP languages created equal. Exactly - unless you're trying very hard, you're unlikely to beat C++ polymorphism with your OOP code in a different language. Which makes Casey's argument that much stronger. C++ with its relatively unsophisticated OOP and minimal overhead on everything, is as fast as you're going to get, so it's good for showing just how slow that still is if you f…

> C++ with its relatively unsophisticated OOP and minimal overhead on everything, is as fast as you're going to get

No it isn't. If your C++ compiler isn't devirtualising at all (implied by the article) it'll get stomped on by anything doing inline caching [0] which will generate the switch-case code. The JVM does that for example.

[0] https://bibliography.selflanguage.org/_static/pics.pdf

Re: “Clean” code, horrible performance

#572
post #517
post #263

Earlier quoted context omitted.

100%, I’ve done tonnes of (backend) performance optimization, profiling, etc. on higher level applications, and the perf bottlenecks have never been any of the things discussed in this article. It’s normally things like: - Slow DB queries - Lack of concurrency/parallelism - Lack of caching/memoization for some expensive thing that could be cached - Excessive serialization/deserialization (things like ORMs that create…

I'd actually say this article is generally unhelpful - it's good to be aware but as someone who works on sorting out performance critical things I want the code to be as clean as humanly possible going in. Whether you write clean or dirty code if you're a junior developer you're probably not going to write performant code and even senior devs may be able to sniff what might be a bottleneck in advance but most of us h…

"Whether you write clean or dirty code"

I feel like there's a misunderstanding here. Casey is clearly not against writing non-capitalized clean code at all. His code in the end is "cleaner" than what he criticizes IMO. What he is criticizing here is capitalized (and possibly trademarked) "Clean Code", the book and philosophy spearheaded by Uncle Bob.

Re: “Clean” code, horrible performance

#573

Earlier quoted context omitted.

Casey's implied point is that clean code is already sacrificing performance from the start. And of course real life tells us that those "performance tweaks" will never happen. There is this popular wisdom that security must be designed for from the start, and cannot be just added after the fact. Performance is like that too, except worse, because you actually can add security after the fact - worst-case, you treat th…

This isn't true in my experience. Even in the context of games development. It pays to be simple at the outset because you often need to iterate code to get it right and writing and iterating optimised code is harder and slower than just doing something simple first. And YES, we ALWAYS went back and optimised the slow bits.

But "being simple from the outset" is exactly what Casey is advocating here. Start with the simple code, that he ends up with, rather than optimizing for a "Cleanliness" metric.

His final code is definitely simpler than the alternative, which would probably involve several files in another environment.

Sure, he does reach for a benchmark, but that's merely to demonstrate the end result.

Re: “Clean” code, horrible performance

#575

Earlier quoted context omitted.

I don't see how the code snippets presented are less maintainable.

I do. Because I was asked to add a convex polygon and calculate its area. And now the shape_union must be rewritten from scratch. ... And maybe we want set-operations in the future...

> And now the shape_union must be rewritten from scratch.

We spend most of our time reading code. If the Casey's code snippets are easier to reason about (which they are, especially as the codebase get larger), that's a big win. I'd imagine you want to optimize for code that is easy to (re)write, rather than minimize the number of key strokes while increasing the time spent understanding the code.

Re: “Clean” code, horrible performance

#576
post #179

I think the author is taking general advice and applying it to a niche situation. > So by violating the first rule of clean code — which is one of its central tenants — we are able to drop from 35 cycles per shape to 24 cycles per shape Look, most modern software is spending 99.9% of the time waiting for user input, and 0.1% of the time actually calculating something. If you're writing a AAA video game, or high perfo…

What does it matter if it does this 0.1% ten times slower than it could? Then user will have to wait for the software which slows the most expensive component of the whole work setup, the human.

[deleted]

Re: “Clean” code, horrible performance

#577
post #179

I think the author is taking general advice and applying it to a niche situation. > So by violating the first rule of clean code — which is one of its central tenants — we are able to drop from 35 cycles per shape to 24 cycles per shape Look, most modern software is spending 99.9% of the time waiting for user input, and 0.1% of the time actually calculating something. If you're writing a AAA video game, or high perfo…

What does it matter if it does this 0.1% ten times slower than it could? Then user will have to wait for the software which slows the most expensive component of the whole work setup, the human.

It matters because, to give an example, Facebook still isn't fast enough to keep up with my typing speed. And I'm not that fast.

Re: “Clean” code, horrible performance

#578

Earlier quoted context omitted.

People did notice. Quite a few happy users are glad signature verification took less than a second instead of more than 3. Or 30, if you compare to some of the alternatives. Others love the fact it uses 2KB of stack space instead of 5. Monocypher's speed was actually an important component in its success in the embedded market, even though I didn't explicitly target it initially (I was lucky my portability driven dec…

You need to do some research on how to get modern C/C++ compilers to vectorize.;-) No assembly required, and not that hard to restructure code. (But MUCH easier in C++).

So far it seems like if you have some parsing or formatting task that can be trivially vectorized, the compiler will never do that, and you absolutely must use intrinsics.

Re: “Clean” code, horrible performance

#579

Earlier quoted context omitted.

How does an organization which has been built on 99% not doing optimization recognize the one percent where it matters a lot?

Profiling. If you're not profiling, you're completely wasting your time. The 1% is almost never where you think it is. And when you do identify the 1%, you need to be testing optimizations with a profiler constantly while optimizing. Profile. Do some optimization. Profile again. Roll back if not successful. Repeat until done. It's impossible to optimize well if you're not doing profiling. The ultimate tools would be…

A hash table that accesses a minimum of 2 cache lines per query can be algorithmically correct and also admit a 100% speedup.

Re: “Clean” code, horrible performance

#580
post #487

Earlier quoted context omitted.

Author could use a little more memoization in his example, but I suspect that breaks some of the simplicity of his argument. If shape Area is computed often enough that you care about inlining the calculation, why not compute & store it every time the height / width change. That’d be easy enough in an architecture based on information hiding, and might illustrate a legitimate engineering trade-off between those archi…

Right? His Area() function does the calculation from the scratch every call. Either a) make the Shape immutable and calculate area once, at create time, or have the mutator functions recompute the area when they are called. At that point Area() just returns an f32, and the compiler can do all kinds of optimizations.

Speaking of mutators, his example depends the code executing in a single thread. What happens if calls to mutate the shape and calls to calculate the area are interleaved?
Post reply on HN