4 ms·
It's amazing that Zig is faster than both Rust and C++. Kudos to the Zig team & Andrew Kelly! I wonder what optimizations Zig does that lets it generate machin
by winter_blue 4y ago
It's amazing that Zig is faster than both Rust and C++. Kudos to the Zig team & Andrew Kelly!
I wonder what optimizations Zig does that lets it generate machine code / LLVM bitcode faster than both C++ and Rust (which certainly have larger teams backing them), at least in the case of this Gameboy emulator project.
- cma 4y agoDoes zig have computed goto? That's important for emulators and virtual machines and C/C++ don't have it. Projects will often go out of their way to have a MinGW/gcc built module for core loops with that (gcc has it as an extension) even if the main project is built with MSVC.
- nerpderp82 4y agoIf Rust wasn't able to elide bounds checks, that is most likely where the perf difference is from. Analyzing the output the assembly output from goldbolt or looking at the MIR can help. https://stefan-marr.de/2022/10/cost-of-safety-in-java/ https://stefan-marr.de/2022/10/cost-of-safety-in-java/ Unsafety buys you a little more performance, but the baseline should the safe version, not the unsafe version. It is like having to explain on a case by case basis why you aren't using lead pipes for this application. Always default to safety. The difference between safe and unsafe native code is usually single digit percentage points. Or weeks on a Moore scale.
- cma 4y agoI think you replied to the wrong comment, mine was about zig vs C++.
- nerpderp82 4y agoI am talking about the whole stack of benchmarks and why there is a spread in perf. I am replying to you and the top level comment, if only the convos were a graph and not a tree.
- vjerancrnjak 4y agoThis should also be the case for nim. Generated C always looks very simple with -d:danger (when all memory access checks disappear).
- cb321 4y agoIf I do nimble build -d:lto -d:danger --passC:-march=native I get 1920 fps while if I do nimble build -d:lto -d:release --passC:-march=native I still get 1775 fps. So, at least for Nim, the checks are only a 1.08x slowdown..Not so bad compared to the 2521 vs 1626 = 1.55x Zig-Rust slowdown on the author's machine. Heck, I see 1.33x differences in run times between the first & second run of the rust branch of his benchmark, but only 1.05x diffs in run times between 1st & 2nd Nim branch. In my experience, reasoning about things like this is rarely as simple as "bounds checks" which are (often) the most highly predictable branches.
- vjerancrnjak 4y agoTrue. Recently I noticed that std/sha1 takes 8x the time on M1 release vs danger. Yet on amd64 it's only a <10% difference.
- Shish2k 4y agoYeah, I’m really not sure how it managed that. I am slightly suspicious, because while I was working on the zig version I spent more time running into compiler bugs[1] than writing my code, and so there’s a chance that it’s running so fast by throwing away random chunks of important behaviour… but it still passes all of the test suite, so as far as I can tell this specific build is working correctly. [1] half the time I’d make the compiler crash; the other half it would generate a binary which crashes at runtime, with weird heisenbug behaviour like “adding a print statement to log how far down a function I am causes the code to stop crashing at all” — like right now there is a load-bearing print statement which shows the address of the SDL Window object, because otherwise the compiler seems to optimise the Window out of existence and then a few lines later it segfaults on the null pointer…
- sirsinsalot 4y ago> a load-bearing print statement Is the most glorious thing I ever heard.
- kristoff_it 4y ago> like right now there is a load-bearing print statement which shows the address of the SDL Window object, because otherwise the compiler seems to optimise the Window out of existence that sounds like you have undefined behavior in your program