Earlier quoted context omitted.
I think clang-format is definitely relevant; the take-away here is that no formatter should change the order of includes. I was wondering about this only yesterday - tidying up some C++ and C code. I don't remember any standard that says it's OK to re-order headers, and clearly it can matter a lot.
That wouldn't be my take away. My takeway would be anything that changes in semantics or performance due to header includes should be considered a bug by the (possibly joint) writers of the involved headers. clang-format is an innocent victim here. Maybe I should make that clearer.
Clang Format Tanks Performance
131–140 of 156 posts
Re: Clang Format Tanks Performance
#132Earlier quoted context omitted.
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 th…
SortIncludes: falseRe: Clang Format Tanks Performance
#133I may eat downvotes but here's an honest opinion nonetheless: this article shows almost exactly why I wouldn't touch C++ with a ten-foot pole still, after running away screaming from it 11-12 years ago. Not saying it's an unique problem with C++'s tooling. I'm just saying that it has been my experience that one is much more likely to stumble upon such horrors while working with C++ as opposed to at least 7 other lang…
> Don't take this as trash-talking, though. I simply want to get things done, not fight my environment. I think people don't understand just how badly C++ is broken in reality (vs conceptually) until their paycheck is tied to a real, years-old, multi-developer C++ project. It is not trash talking, it is pointing out truths. It goes well beyond "any long-lived project has its issues." I think you and I (and many other…
> It goes well beyond "any long-lived project has its issues."
I heard this mantra as a justification for bad coding practices likely 500 times.
I appreciate that C++ still drives a lot of our virtual world but that's more a proof of the tenacity of those programs' creators than the virtues of C++ itself. IMO it's time tools like `ripgrep`, `dua` / `ds-cli` (both calculate directory contents' sizes) to become the norm: Rust tools, multicore friendly, insanely fast, and with no quirks and weirdly interacting CLI switches.
Re: Clang Format Tanks Performance
#134Earlier quoted context omitted.
Only if you use unsafe Rust, otherwise you'd have to prove that safe Rust semantics are enough to describe the same operations used to squeeze out that performance in C/C++.
It's more complicated than that. Compilers love restrictions, because that means they can optimize more aggressively. And there are features that Rust doesn't have that C++ does have that can make Rust faster; for example, because Rust doesn't have move constructors, moving is an incredibly cheap operation, whereas it can execute arbitrary code (including throwing an exception!) in C++. There are also... I don't know…
Rust can use less ways to do the same thing, I keep hearing from people, and I am hopeful it can be tackled in the future with clever deprecations or simply de facto libraries / ways of doing things.
Thanks for your hard work, it's much appreciated.
Re: Clang Format Tanks Performance
#135Earlier quoted context omitted.
Not really too bizarre. Header files should include or declare everything they need; they should not introduce include-order dependencies. Listing your includes in lexicographic order is a good way to enforce header completeness.
One other ordering I've encountered which helps remove errors is to list the headers in reverse generic order. Meaning that you go from the most specific header files to the least specific. So and would be getting included last. This helps ensure that your specific project level header files have all the necessary forward declares and includes to be a fully functioning and complete header.
Re: Clang Format Tanks Performance
#136Earlier quoted context omitted.
One other ordering I've encountered which helps remove errors is to list the headers in reverse generic order. Meaning that you go from the most specific header files to the least specific. So and would be getting included last. This helps ensure that your specific project level header files have all the necessary forward declares and includes to be a fully functioning and complete header.
I also sort my includes this way. The trouble is, determining how generic an include (inclusion?) is is a fuzzy problem. Sometimes I get stuck trying to figure out which header is more abstract, and at times I've run into side effects like this even with reverse generic sorting.
In the end though you'll have to make a decision on how to sort the projects and which one is more or less specific than another. Kind of like deciding to just sort by pointer address if all else is equal.
Re: Clang Format Tanks Performance
#137Earlier quoted context omitted.
Yes, at best 20% slower but can be far more slower if you hit worst case scenario.
Where did you pull those numbers? Looking at https://benchmarksgame-team.pages.debian.net/benchmarksgame/... While the worst case is 40% slower (where even C perfored abysmally), most of the time the Rust is within a 10% margin of error, and in quite a few cases it's faster.
Re: Clang Format Tanks Performance
#138Earlier quoted context omitted.
I agree with most of that, although as the author I think it's still clickbait in the sense that: 1) clang-format is not really at fault here at all - the same effect could have happened by adding a new header, reordering the headers manually, switching to a system with a different libc version or a different transitive header include tree, etc. 2) The title doesn't tell you wtf is up. You have to get at least half w…
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.
I agree that a formatting tool changing the behavior or performance is a serious issue, but I don't think it's a bug in clang-format in that I suspect it is deliberate design choice, and users can opt out if they want. Maybe the default could be changed or more visible warnings added to the documentation, but the real fix here needs to be in glibc.
Re: Clang Format Tanks Performance
#139Earlier quoted context omitted.
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
#140Earlier quoted context omitted.
The title was basically clickbait. It reflects how I encountered the issue, but the investigation doesn't have much of that, because I was starting from a point where I suddenly had a slow and fast algorithm (the actual scenario was more complicated than shown). The investigation doesn't have much to do with clang-format because I'm just trying to see why a raw loop is faster, and ultimately has nothing to do with "r…
I bet the performance would look different in a real program anyways. The random input data probably results in more branch predict misses than would occur in normal text, and the tight loop of the benchmark basically ensures the lookup table is always in cache.
In addition to more instructions and a function call, the slow version has many more memory dereferences, so if everything is very cold it is likely to suffer more misses.