11 ms·
Zig builds are getting faster
- jtrueb 1y agoWow!
- Ygg2 1y agoIt's a bold strategy - let's see if it works out for them. But from what I remember, this still uses the LLVM backend, right? Sure, you can beat LLVM on compilation speed and number of platforms supported, but when it comes to emitting great assembly, it is almost unbeatable.
- measurablefunc 1y agoI don't really get the obsession w/ compiler performance. At the end of the day you are trading performance optimizations (inlining, dead code elimination, partial evaluation, etc) for compile times. If you want fast compile times then use a compiler w/ no optimization passes, done. The compile times are now linear w/ respect to lines of code & there is provably no further improvement you can make on that b/c any further passes will add linear or superlinear amount of overhead depending on the complexity of the optimization.
- tom_ 1y agoBut if those passes (or indeed any other step of the process) are inefficiently implemented, they could be improved. The compiler output would be the same, but now it would be produced more quickly, and the iteration time would be shorter.
- dustbunny 1y agoAny delay between writing code and seeing the result is empty space in my mind where distractions can enter.
- pfg_ 1y agoThe reason to care about compile time is because it affects your iteration speed. You can iterate much faster on a program that takes 1 second to compile vs 1 minute. Time complexity may be O(lines), but a compiler can be faster or slower based on how long it takes. And for incremental updates, compilers can do significantly better than O(lines). In debug mode, zig uses llvm with no optimization passes. On linux x86_64, it uses its own native backend. This backend can be significantly faster to compile (2x or more) than llvm. Zig's own native backend is designed for incremental compilation. This means, after the initial build, there will be very little work that has to be done for the next emit. It needs to rebuild the affected function, potentially rebuild other functions which depend on it, and then directly update the one part of the output binary that changed. This will be significantly faster than O(n) for edits.
- timschmidt 1y ago> The reason to care about compile time is because it affects your iteration speed. You can iterate much faster on a program that takes 1 second to compile vs 1 minute. Color me skeptical. I've only got 30 years of development under the belt, but even a 1 minute compile time is dwarfed by the time it takes to write and reason about code, run tests, work with version control, etc. Further, using Rust as an example, even a project which takes 5 minutes to build cold only takes a second or two on a hot build thanks to caching of already-built artifacts. Which leaves any compile time improvements to the very first time the project is cloned and built. Consequently, faster compile times would not alter my development practices, nor allow me to iterate any faster.
- zdragnar 1y ago> Consequently, faster compile times would not alter my development practices, nor allow me to iterate any faster. I think the web frontend space is a really good case for fast compile times. It's gotten to the point that you can make a change, save a file, the code recompiles and is sent to the browser and hot-reloaded (no page refresh) and your changes just show up. The difference between this experience and my last time working with Ember, where we had long compile times and full page reloads, was incredibly stark. As you mentioned, the hot build with caching definitely does a lot of heavy lifting here, but in some environments, such as a CI server, having minutes long builds can get annoying as well. > Consequently, faster compile times would not alter my development practices, nor allow me to iterate any faster. Maybe, maybe not, but there's no denying that faster feels nicer.
- deleted 1y ago[deleted]
- ben-schaaf 1y agoclang -O0 is significantly slower than tcc. So the problem is clearly not (just) the optimisation passes.
- rudedogg 1y ago> If you want fast compile times then use a compiler w/ no optimization passes, done. The compile times are now linear w/ respect to lines of code & there is provably no further improvement you can make on that b/c any further passes will add linear or superlinear amount of overhead depending on the complexity of the optimization. Umm this is completely wrong. Compiling involves a lot of stuff, and the language design, as well as compiler design can make or break them. Parsing is relatively easy to make fast and linear, but the other stuff (semantic analysis) is not. Hence why we have a huge range of compile times across programming languages that are (mostly) the same.
- OtomotO 1y agoI think it highly depends on what you're doing. For some work I tend to take a pen and paper and think about a solution, before I write code. For these problems compile time isn't an issue. For UI work on the other hand, it's invaluable to have fast iteration cycles to nail the design, because it's such an artistic and creative activity
- loeg 1y agoPeople are (reasonably) objecting to Clang's performance even in -O0. Still, it is a great platform for sophisticated optimizations and code analysis tools.
- WD-42 1y agoWhen you are writing and thinking about code, you are making progress. You are building your mental model and increasing understanding. Compile time is often an excuse to check hacker news while you wait for the artifact to confirm your assumptions. Of course faster compile times are important, even if dwarfed relatively by writing the code. It’s not the same kind of time.
- deleted 1y ago[deleted]
- indymike 1y agoFaster compiler means developers can go faster.
- bsder 1y ago> but when it comes to emitting great assembly, it is almost unbeatable. "Proebsting's Law: Compiler Advances Double Computing Power Every 18 Years" The implication is that doing the easy, obvious and fast optimizations is Good Enough(tm). Even if LLVM is God Tier(tm) at optimizing, the cost for those optimizations swings against them very quickly.
- mitchellh 1y agoIt only uses the LLVM backend for release builds. For debug builds Zig now defaults to self-hosted (on supported platforms, only x86_64 right now). Debug builds are directly in the hot path of testing your software (this includes building test binaries), and the number of iterations you do on a debug build are multiple orders of magnitude higher than release builds, so this is a good tradeoff.
- brabel 1y agoThe post says the llvm is used in all builds they measured since the self hosted backend still can’t compile ghostty.
- deleted 1y ago[deleted]
- dundarious 1y agoIncorrect, the last build is substantially faster and is using the "native" debug backend.
- mmastrac 1y agoLLVM is a trap. You bootstrap extra fast, you get all sorts of optimization passes and platforms for free, but you lose out on the ability to tune the final optimization passes and performance of the linking stages. I think we'll see cranelift take off in Rust quite soon, though I also think it wouldn't be the juggernaut of a language if they hadn't stuck with LLVM those early years. Go seems to have made the choice long ago to eschew outsourcing of codegen and linking and done well for it.
- deleted 1y ago[deleted]
- OtomotO 1y agoHuh, are there plans on using cranelift for release builds?
- veber-alex 1y agoNo
- 01HNNWZ0MV43FF 1y agoIf it's a small overhead I might
- mmastrac 1y ago"While it does not have the aggressive optimization stance (or complexity) of larger compilers such as LLVM or gcc, its output is often not too far off: the same paper showed Cranelift generating code that ran ~2% slower than V8 (TurboFan) and ~14% slower than an LLVM-based system." -- https://cranelift.dev/ https://cranelift.dev/
- azakai 1y agoThe Cranelift website does have that quote, but the linked paper says > The resulting code performs on average 14% better than LLVM -O0, 22% slower than LLVM -O1, 25% slower than LLVM -O2, and 24% slower than LLVM -O3 So it is more like 24% slower, not 14%. Perhaps a typo (24/14), or they got the direction mixed up (it is +14 vs -24), or I'm reading that wrong? Regardless, those numbers are on a particular set of database benchmarks (TPC-H), and I wouldn't read too much into them.
- stephc_int13 1y agoThe gold standard for compiler speed so far is TCC. (Fabrice Bellard) It is not even super optimized (single thread, no fancy tricks) but it is so far unbeaten by a large margin. Of course I use Clang for releases, but the codegen of tcc is not even awful.
- Rochus 1y agoThe Go compiler is also pretty fast.
- klysm 1y agoMaybe typescript will catch up
- satvikpendem 1y agoIt's being rewritten in Go so yes it will
- serial_dev 1y agoThe compiler might be rewritten in Go, but the Typescript and Go languages themselves are very different. Go’s main objectives were fast builds and a simple language. Typescript is tacked onto another language that doesn’t really care about TS with three decades of warts, cruft and hacks thrown together.
- veber-alex 1y agoIt's hard to say. One the one hand the go type system is a joke compared to typescript so the typescript compiler has a much harder job of type checking. On the other hand once type checking is done typescript just needs to strip the types and it's done while go needs to optimize and generate assembly.
- levodelellis 1y agoI'd call it not terribly slow. IIRC it didn't hit 100k lines on an M2, while I saw over two million on my own compiler (I used multiple instances of tcc since I didn't want to deal with implementing debug info on mac)
- dcsommer 1y agoIs there a straightforward path to building Zig with polyglot build systems like Bazel and Buck2? I'm worried Zig's reliance on Turing complete build scripts will make building (and caching) such code difficult in those deterministic systems. In Rust, libraries that eschew build.rs are far preferable for this reason. Do Zig libraries typically have a lot of custom build setup?
- rockwotj 1y agoFor bazel: https://github.com/aherrmann/rules_zig https://github.com/aherrmann/rules_zig Real world projects like ZML uses it: https://github.com/zml/zml https://github.com/zml/zml
- esjeon 1y agoFYI, build scripts are completely optional. Zig can build and run individual source code files regardless of build scripts (`build.zig`). You may need to decipher the build script to extract flags, but that's pretty much it. You can integrate Zig into any workflow that accepts GCC and Clang. (Note: `zig` is also a drop-in replacement C compiler[1]) [1]: https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html https://andrewkelley.me/post/zig-cc-powerful-drop-in-replace...
- koeng 1y agoI've really appreciated the incremental builds with zig - I really like having a single static binary, and I have an application which uses a few different libraries like SQLite and luau and it compiles at nearly Go speeds. That said, there are definitely still bugs to their self hosted compiler. For example, for SQLite I have to use llvm - https://github.com/vrischmann/zig-sqlite/issues/195 https://github.com/vrischmann/zig-sqlite/issues/195 - which kinda sucks.
- teo_zero 1y agoAnybody knows what exactly prevents Ghostty from being built using the self-hosted x86_64 backend?
- anonymoushn 1y agowell, most of the users are aarch64
- mitchellh 1y agoBugs. The Zig compiler crashes. It’s new and complex, I’m sure they’ll work it out soon.
- commandersaki 1y agoTangential: I've been writing a Java library that is pretty much a JNI shim to a C library. Looking at building a dynamic library for each of the platform / architecture combo is looking like a huge pain in the arse; I'm toying with the idea of using the zig compiler to do the compile / cross compiles and simply be done with it.
- mbrock 1y agodo yourself a favor and try it, Zig ships with headers and libc sources and its own LLVM distribution and makes cross compilation so easy it's just ridiculous, you literally don't have to do anything
- pjmlp 1y agoIf it is a plain shim, and you can use modern Java, I would rather make use of Panama and jextract.
- metaltyphoon 1y agoI've been building a shared lib for both Android and iOS/iPadOS and using jni and jin_fn crate in Rust has been a God sent. Using cargo-ndk simplifies the building process so much.
- mischief6 1y agomy only wish for ghostty is that there was openbsd support. some work needs to be done in the io layer to support openbsd kqueue to make it work.
- loeg 1y agoI'm surprised that whatever IO primitive is used on Mac doesn't work on OpenBSD. Mac has select and some variant of kqueue, right? What is ghostty doing there that doesn't work on OpenBSD? E.g., here it is kqueue-aware on FreeBSD: https://github.com/mitchellh/libxev/blob/34fa50878aec6e5fa8f532867001ab3c36fae23e/src/backend.zig#L17 https://github.com/mitchellh/libxev/blob/34fa50878aec6e5fa8f... Might not be that different to add OpenBSD. Someone would begin here: https://github.com/mitchellh/libxev/blob/main/src/backend/kqueue.zig https://github.com/mitchellh/libxev/blob/main/src/backend/kq... It's about 1/3 tests and 2/3 mostly-designed-to-be-portable code. Some existing gaps for FreeBSD, but fixing those (and adding OpenBSD to some switch/enums) should get you most of the way there.
- mischief6 1y agoi know freebsd and macos have similar implementations, but it is just different enough that it is nontrivial to make work. i had started fixing it locally but didn't quite get it working, since i'm not really that familiar with zig, although i like the idea of the language.
- geokon 1y agoTrying to understand the Zig goals a bit better.. If you care about compilation speed b/c it's slowing down development - wouldn't it make sense to work on an interpreter? Maybe I'm naiive, but it seems the simpler option Compiling for executable-speed seems inherently orthogonal to compilation time With an interpreter you have the potential of lots of extra development tools as you can instrument the code easily and you control the runtime. Sure, in some corner cases people need to only be debugging their full-optimization-RELEASE binary and for them working on a interpreter, or even a DEBUG build just doesn't makes sense. But that's a tiny minority. Even there, you're usually optimizing a hot loop that's going to be compiling instantly anyway
- IshKebab 1y agoI wouldn't say games are a corner case.
- dontlaugh 1y agoFor games you have to compile release builds almost all the time anyway, otherwise performance wouldn’t be playable.
- flohofwoe 1y agoThat's only true for badly written game code though ;) Even with C++ and heavy stdlib usage it's possible to have debug builds that are only around 3..5 times slower than release builds in C++. And you need that wiggle room anyway to account for lower end CPUs which your game should better be able to run on.
- dontlaugh 1y agoIf you target consoles, you’re already on the lowest end hardware you’ll run on. It’s extremely rare to have much (if any) headroom for graphically competitive games. 20% is a stretch, 3x is unthinkable.
- self_awareness 1y agoFor me, Zig the language is "meh", but Zig the toolchain is very interesting. It's really ambitious, to the point I think it can't work in reality in the long term, but I want it to succeed.
- sgt 1y agoHonestly a bit surprised that he waits 16 seconds every minor change to Ghostty while developing. That sounds painful. Glad Zig build times are getting faster though, and I understand he is still on LLVM.
- loeg 1y agoI work in a large C++ codebase where incremental builds can take minutes. It's flow-interrupting, but doesn't make it impossible to be productive. You just can't rely too heavily on tight printf debugging cycles or you waste a lot of time waiting.
- Simran-B 1y agoHow does Zig's compilation and codegen compare to TPDE? The claim is that it's 10-20x faster than LLVM with -O0 but with limitations.
- 62 1y ago[dead]
- ozgrakkurt 1y agoSpeed feels even faster than 20x and debug mode code runs ok. Don’t know about assembly quality difference
- onetom 1y agoGreat. It's finally as snappy as recompiling the "Borland Pascal version of Turbo Vision for DOS" was on an Intel 486 in 1995, when I graduated from high school... They C version of Turbo Vision was 5-10x slower to compile at that time too. Turbo Vision is a TUI windowing framework, which was used for developing the Borland Pascal and C++ IDEs. Kinda like a character mode JetBrains IDE in 10 MB instead of 1000 MB... https://en.m.wikipedia.org/wiki/Turbo_Vision https://en.m.wikipedia.org/wiki/Turbo_Vision
- ComputerGuru 1y agoAre their ghostty builds statically linked by default or does zig follow in the footsteps of the C/C++ world and dynamically link everything? If statically linking (like rust) then a huge part of the incremental build times for apps with external dependencies is the lack of incremental linking in any of the major linkers. Wild linker is working on becoming the answer to this: https://github.com/davidlattimore/wild https://github.com/davidlattimore/wild
- tredre3 1y agoghostty statically links all its zig dependencies. The only dynamic libraries I can see are the usual suspects (libc, X11, Wayland, OpenGL, GTK, glib, libadwaita, etc).
- alexrp 1y agoZig supports both linking modes but has a strong preference for static linking - it's the default in most contexts.
- lerno 1y agoWhile LLVM certainly is a problem, consuming over 90% of compile times both for C3 and Odin, it should be noted that both languages compile MUCH faster than Zig, achieving in general sub second compile times while using LLVM and without incremental compilation. So the question could be asked: ”what is making Zig so slow to compile” as both languages have similar feature sets compared to that of Zig.
- lerno 1y agoI should add that there are a few candidates: 1. Zig uses three(!) frontend IRs, Odin and C3 only one. 2. Zig relies heavily on comptime to provide most of its language features. C3, which has a similar set of features, doesn’t encourage excessive use of compile time and offers more features built into the language (for example format checking is a builtin, whereas in Zig it’s userland, even if C3 has the capability to do it like Zig). Although note that Zig only checks code directly traced, whereas C3 will check all code, and so will - esp for simple code - check much more code than Zig does. 3. Zig generates A LOT of code for even just a ”safe” Hello World. On top of that, maybe there are just some other inefficiencies that hasn’t been addressed yet by the Zig team? Even though I have stakes in the game I hope Zig gets faster. We need to move away from the illusion that Swift, C++ and Rust compilation speeds are anywhere near acceptable.