Live data from Hacker News

Clang Format Tanks Performance

travisdowns.github.io

111–120 of 156 posts

Re: Clang Format Tanks Performance

#111

Earlier quoted context omitted.

That's what I keep hearing but here on HN periodically do pop up some benchmarks that show Rust being stomped. But oh well, most benchmarks aren't pure or non-opinionated so there's that as well. So far I like Rust quite a lot but -- as I said in another sibling comment -- its procedural style and syntax aren't stellar, in my eyes at least.

since simd intrinsics got introduced there shouldn't be any reason for rust to get 'stomped'

Sorry, I don't mean to be demeaning. I am aware Rust's creators make huge strides and I am absolutely on their side. I already prefer Rust over a lot of languages, C and C++ included.

Just having some healthy skepticism, apologies if it reads like anything else.

Re: Clang Format Tanks Performance

#112
post #95

Earlier quoted context omitted.

While Go and Elixir might indeed be slower, Rust is designed to generate optimal code and offer zero-cost abstractions like C and C++ and I would expect it to do so in this case.

That's what I keep hearing but here on HN periodically do pop up some benchmarks that show Rust being stomped. But oh well, most benchmarks aren't pure or non-opinionated so there's that as well. So far I like Rust quite a lot but -- as I said in another sibling comment -- its procedural style and syntax aren't stellar, in my eyes at least.

Well, generally you can, approximately, given C/C++ code, produce Rust code that should give equivalent LLVM bitcode to the one produced by clang on the C/C++ code, so it should not be possible for Rust to routinely lose benchmarks to clang with a significant margin given enough effort in benchmark construction.

Re: Clang Format Tanks Performance

#113
post #96

Earlier quoted context omitted.

If you want to just get things done then this sort of complexity wouldn't impact you in the slightest using C++. You could just write code without needing to know this information. This is something for people really needing to squeeze performance out of systems. If you are looking for performance though, other languages have similar but different pitfalls and bits of esoteric knowledge that you need. Constructs that…

True. I am simply looking for a compiled not-far-away-from-C++ levels of performance language, plus one with the least amount of pitfalls / gotchas / WTFs to avoid. So far Rust seems to hit a sweet spot, although its style (procedural) and syntax leave much to be desired.

Achieving “not far away from C++ levels of performance” with anything but a procedural-style language is very difficult, rare, and usually comes with severe trade-offs, unfortunately.

For example: Haskell has been trying to bring the performance of C to a functional language for almost 30 years now. While Haskell is a great language with impressive performance for its category, I don’t think anyone believes it renders C/C++ obsolete for scenarios where predictably high performance is crucial.

This is an interesting topic to me, because while I try to find ways to write high-performance code as functionally as possible, I can’t seem to escape the relationship where more procedural-styled code usually yields consistently/predictably higher performance.

Functional (and other paradigms) can sometimes match C’s performance -- but in non-toy scenarios, the “sometimes” clause here compounds its probabilities to ultimately become “virtually never”, as the scope and complexity of a real project grows.

As a result, performance-critical projects written in languages without predictable performance characteristics often evolve into a situation later in development where 90% of your development time is spent poking at 'black boxes' (the compiler optimizer and garbage collector), hoping (sometimes futilely) that you can prod it into spitting out the procedural machine code patterns you already knew you needed anyway — if you’re lucky. And what makes this even worse is that this situation usually arises late enough into development that it's very costly (if not impossible) to backtrack and rewrite everything in a procedural language.

Of course, writing procedurally ends up trading off readability and robustness too human error, vs better performance. I too wish there was a better way to achieve both — I just haven’t found it yet.

Re: Clang Format Tanks Performance

#114

Earlier quoted context omitted.

True. I am simply looking for a compiled not-far-away-from-C++ levels of performance language, plus one with the least amount of pitfalls / gotchas / WTFs to avoid. So far Rust seems to hit a sweet spot, although its style (procedural) and syntax leave much to be desired.

Achieving “not far away from C++ levels of performance” with anything but a procedural-style language is very difficult, rare, and usually comes with severe trade-offs, unfortunately. For example: Haskell has been trying to bring the performance of C to a functional language for almost 30 years now. While Haskell is a great language with impressive performance for its category, I don’t think anyone believes it render…

Insightful. I will be treading a very similar path soon.

So, isn't there a way to emulate FP's `map` mechanics for example, in Rust, without losing performance?

EDIT: To reflect your edits, this is why I want to learn Rust. I am as happy as one can be with Elixir due to Erlang's transparent super-robust and predictable parallel performance; this thing simply does not lag! However, I'd like to be prepared and be able to utilise Rust on the performance hot-spots.

Re: Clang Format Tanks Performance

#115
post #70

Earlier quoted context omitted.

It is by convention that C/C++ headers rely on preprocessor state to determine what blocks to reveal, macros to use, et al. It is quite common to have an auto-generated configuration header, for instance; or a precompiled header; or optional headers that, when present, mutate the behaviour of other headers. Every time you run a configure script for a C project there's a good chance you're interacting with code in thi…

Yeah, and if you want to use clang-format include reordering in such a project, you should read the docs for clang-format's "IncludeCategories". It allows you to separate your includes into blocks by providing regexes and associated priorities. Alphabetic sorting is done only within a block. It's not like clang-format was written by idiots who never used the language before. Maybe read up on what the tool actually do…

I'm not mad?

I think it's a harmful anti-feature that's worthy of criticism.

Re: Clang Format Tanks Performance

#116
post #86

Earlier quoted context omitted.

Headers really shouldn’t be affecting each other. Header order shouldn’t matter. The fact that it does is arguably a bad design flaw in C/C++, although the C modules system pushed by Apple fixed this.

Tooling developers don’t get to say “it shouldn’t matter”. It does matter, so the tools should account for this.

clang-format does account for this: if you break your includes into groups with blank lines, clang-format will sort within but not across the groups. That is, clang-format offers a crude but simple API to the programmer to express which headers have order dependency, and which don't.

Given that headers can have order dependency, it is sadly part of a C++ programmer's responsibility to know which do, just as it is their responsibility to know which functions have side-effects, etc. If they are using clang-format, it is then their responsibility to communicate this knowledge to it.

Re: Clang Format Tanks Performance

#117
post #6

Can the std::transform version be written without a lambda? std::transform(buf, buf + size, buf, toupper);

Yes, it can! In fact I had that at some point and clobbered it with a git reset (the perils of developing on two machines and once and using git a sync mechanism). Fixed [1] and credited. --- [1] https://github.com/travisdowns/travisdowns.github.io/commit/...

This could actually change performance though as the lambda version gives you a unique templace instantiation of std::transform while the non-lambda version requires std::transform to be inlined into the caller (or cloned to an argument-specific version) before the compiler can make any optimizations based on its knowledge of toupper.

Re: Clang Format Tanks Performance

#118
post #77
post #51

Earlier quoted context omitted.

Of course clang format is at fault; reordering includes, even standard or system includes, will almost certainly effect how a complex C/C++ program compiles. That's just how it is, with the preprocessor and such. This is a _bad_ clang-format bug.

You can disable include reordering in clang-format. I don't think this is a bug, because I see the default here as a matter of policy decision.

Given that reordering includes can have consequences, reordering includes blindly and casually like the OP is a form of Russian roulette: an order that works should be preserved until it stops working.

The article describes false complexity caused by looking atr the issue in the wrong way: a "mysterious" performance problem, to be diagnosed, rather than the obvious consequence of a broken workflow that includes an extremely hazardous operation.

In a voluntary header reordering experiment, all kinds of breakage could be detected with a trivial before and after comparison of compiled code.

Re: Clang Format Tanks Performance

#119

Author here, happy for any feedback. I'll own up to misleading-and-possibly-clickbait title, I just gave up trying to think of anything better without revealing the conclusion.

Just to make sure I'm understanding this correctly: the performance issue you found actually amounts to include-order dependent behavior in GCC and glibc; clang doesn't really have anything to do with anything here except that you used its code formatter to sort your include statements. If that's the case, the clickbait-y headline's bordering on useless, since the performance differences here have nothing to do with…

It would actually be interesting to see if this phenomenon happens with clang, which has its own implementation of the standard library. And perhaps with musl libc or some such.

Re: Clang Format Tanks Performance

#120

Earlier quoted context omitted.

Achieving “not far away from C++ levels of performance” with anything but a procedural-style language is very difficult, rare, and usually comes with severe trade-offs, unfortunately. For example: Haskell has been trying to bring the performance of C to a functional language for almost 30 years now. While Haskell is a great language with impressive performance for its category, I don’t think anyone believes it render…

Insightful. I will be treading a very similar path soon. So, isn't there a way to emulate FP's `map` mechanics for example, in Rust, without losing performance? EDIT: To reflect your edits, this is why I want to learn Rust. I am as happy as one can be with Elixir due to Erlang's transparent super-robust and predictable parallel performance; this thing simply does not lag! However, I'd like to be prepared and be able…

The major problem with functional programming is that many idioms requires a garbage collector. For example having pure operations on binary trees by just replacing dirty nodes leaving all old references intact wouldn't be possible in rust.
Post reply on HN