Live data from Hacker News

Zig's Incremental Compilation Internals

mlugg.co.uk

141–150 of 292 posts

Re: Zig's Incremental Compilation Internals

#141
post #129

Earlier quoted context omitted.

I think it's also a matter of experience - someone used to writing code in unsafe low level languages has a different approach to solving problems and may find Rust gets in the way. I actually started with C++ and after writing a reasonable amount of it I found myself wondering why I had to keep track of lifetimes, nullability etc in my head when it was so easy to mess those up. I kind of discovered "why Rust" from f…

> I kind of discovered "why Rust" from first principles and from then on I was hooked. I get it. The language certainly does appeal to some people, and I can understand why, just as I understand why it does not appeal to others. > I found myself wondering why I had to keep track of lifetimes, nullability etc in my head when it was so easy to mess those up. And I agree with that, but my conclusion (after decades of ex…

I think the only argument I’d make about high level programming languages is that software continues to outpace hardware development in sucking up as much performance gains as possible. One program written in a slower, garbage collected, high level language is ok, when they are all it’s bad. I think eventually we’ll get to a point where we won’t have to think about memory management anymore but we aren't really there yet. Heck, software written in C++ like browsers are dog slow, imagine if they were written in Java…

Re: Zig's Incremental Compilation Internals

#142
post #65
post #57

Earlier quoted context omitted.

I’ve been watching this debate online and in my opinion both sides are guilty. Fil is intentionally trying to be funny or at least “interesting “ when he makes his points and I, for one, enjoy his humor, which includes having a go at Rust and other languages. It seems Rust people just can’t take a little criticism, even when it comes from a clearly trolling language! Yes it’s true Rust has an escape hatch, and we’ve…

Yes! I think Fil is great so far but I think as he gets a bigger audience he should, well, consider that and focus on clarity a little more than humor. You can see Andrew’s growth in that respect. Rust folks, this whole thing is a thread about Zig’s new feature - not even a memory safety-related feature! - and we cannot spend the whole damn time talking about Rust. Steve, even you - I don’t believe I have ever seen y…

I think the derailment of this thread into "is Rust's memory safety good or not" is unfortunate and tedious (this debate must have happened hundreds of times by now on this site alone), but I also think it's unfair to lay the blame on Steve for this. Steve left a thoroughly glowing comment praising Zig's work on compiler performance, and comparing to his perspective on the early days of Rust. He mentioned in passing that he's not a Zig user due to preferring to work in memory-safe languages, which was polite, brief, clearly his personal position, and in my opinion an acceptable way to disclose his relationship with Zig without derailing the thread to be about memory safety.

This comment spawned two subthreads. One of them was focused on the differences between Rust and Zig's compilation model, which is directly relevant to the article and illuminating regarding the engineering tradeoffs.

In the other subthread, pron posted paragraphs and paragraphs arguing about what memory safety really means and whether or not Steve is right to have his opinion that Rust is "safe". This tangent had essentially nothing to do with the content of Steve's comment; it (and not Steve's initial comment) was the point where the thread was derailed from the topic of Zig's incremental compilation model. Steve responded politely in this thread to comments and questions directed at him, but did not fan the flames or take the thread further into off-topicness. If the moderators collapsed pron's comment or detached it and pinned it to the bottom of the page, this comment thread would be much better and much more respectful to the Zig project.

I think the RESF trope is just about dead now; it's given way to the Rust Detractor Strike Force showing up to turn unrelated threads into tangential arguments about why Rust is bad.

Re: Zig's Incremental Compilation Internals

#143
post #129

Earlier quoted context omitted.

> I kind of discovered "why Rust" from first principles and from then on I was hooked. I get it. The language certainly does appeal to some people, and I can understand why, just as I understand why it does not appeal to others. > I found myself wondering why I had to keep track of lifetimes, nullability etc in my head when it was so easy to mess those up. And I agree with that, but my conclusion (after decades of ex…

I think the only argument I’d make about high level programming languages is that software continues to outpace hardware development in sucking up as much performance gains as possible. One program written in a slower, garbage collected, high level language is ok, when they are all it’s bad. I think eventually we’ll get to a point where we won’t have to think about memory management anymore but we aren't really there…

I originally came to Java because of the better performance it offered compared to C++ in large programs. The JVM is specifically designed to remove some of the fundamental performance overheads that low-level languages suffer from, and manifest especially when programs grow large (and a browser is quite large). So when someone talks to me about "GC languages" being slow and low-level languages being fast, I know they've not had much experience with either Java or low level languages, nor do they understand modern compilers and memory management. Java offers strictly more optimisation opportunities than low-level languages, in compilation as well as in memory management. What it gives up in exchange is low-level control (including worst-case performance), but it is low-level languages that sacrifice performance (especially average-case performance) in exchange for the control they need. Not being able to move pointers freely and not being able to deoptimise and recompile at runtime are serious impediments to modern optimisation, but low-level languages gladly give that up because they're not optimised for performance but for precise control.

In particular, modern moving collectors were designed for the purpose of removing the high overheads of malloc/free allocators that make heap memory management so expensive in low-level languages (and in any language that uses non-moving memory management strategies). The reason code in low-level languages tries to avoid things like heap allocation and virtual dispatch on the hot path is not because these things can't be super-fast (most virtual calls in Java are faster than many static calls in C), but because they are slow in low level languages because of their constraints.

Re: Zig's Incremental Compilation Internals

#144

Earlier quoted context omitted.

My main problem with Fil-C is that it combines the worst parts of C with the worst parts of a GC language. In a language like C (or Zig), you need to manually manage memory. This makes programming a lot more complex, and it's really easy to accidentally mess up. Especially in large projects which have a lot of separate modules. The biggest advantage of using a garbage collector is that you don't have to think about f…

> GC languages are slower This is not necessarily true. It depends on a language, e.g. Go is slow, Nim[0] is extremely fast with conventional GC and slightly faster with ARC/ORC[1]. GC programs can be faster than manually managed ones in some cases. It's just manual memory management gives you more control of where and when free is called. And a good type system is a privelege that gives Nim more control with destruc…

Good to know! Would there be any way languages like Go or C# could adopt Nim's new garbage collector? If it's better, what stops other languages from using it?

> GC programs can be faster than manually managed ones in some cases.

I've seen poorly written programs in C/C++/Rust which are slow because they allocate millions of tiny objects. Its true that generational GCs can be faster in this case. But you usually get much better performance again by using arenas and such. The reality is that I know more about the lifecycle of my data than my compiler. If you know what you're doing, you can take advantage of this information to write better programs.

If you don't want to think about memory management, then I agree - you're usually better off using a language with a GC. Personally I do a lot of my prototyping in typescript because I can iterate faster when I don't have to think about lifetimes.

Maybe some day Fil-C will run general purpose C code at native speeds, without a high memory overhead. But we're not there yet. I'm not holding my breath.

Re: Zig's Incremental Compilation Internals

#145

I just looked up a Hello World program from the Zig Wikipedia article: const std = @import("std"); const File = std.Io.File; pub fn main(init: std.process.Init) !void { _ = try File.stdout().writeStreamingAll(init.io, "Hello, World!\n"); } That's a lot to follow, just to output a plan-text message, especially after this line: "The primary goal of Zig is to be a better solution to the sorts of tasks that are currently…

Everything it's doing it clear and readable. It's just not as easy to write. It streams the bytes to stdout using the default IO interface, and it can fail. Alternatively, here's a simpler version (prints to stderr). const std = @import("std"); pub fn main() void { std.debug.print("Hello, world!\n", .{}); } In practice, you normally don't want to print messages to stdout. So the increased friction here actually pushe…

the given complicated version's complexity actually just comes from the fact that it's a "more correct" way to write a hello world program, as it manually acquires the stdout File object and acknowledges that printing to stdout can fail. the complexity has nothing to do with stdout vs stderr, you could just use `.stderr()` instead of `.stdout()` (same "friction", it's even the same number of characters). `std.debug.print` is only meant for debugging/development as it gets stderr for you and discards the errors that could happen when writing to stderr.

Re: Zig's Incremental Compilation Internals

#146

This post is really interesting. As a member of the rust-analyzer team, I cannot avoid comparing it to the situation in Rust land. Rust famously has not less (or even more) sophisticated system for incremental compilation, yet its compilation is way slower. I attribute that to two main things: - Language design. Zig was designed for fast and incremental compilation, Rust is just not. For instance, the post states tha…

Isn't most of Rust's compilation overhead from the llvm backend?

That is common wisdom but reality is more complicated. It's true in some projects, but not all.

Re: Zig's Incremental Compilation Internals

#147
post #143

Earlier quoted context omitted.

I think the only argument I’d make about high level programming languages is that software continues to outpace hardware development in sucking up as much performance gains as possible. One program written in a slower, garbage collected, high level language is ok, when they are all it’s bad. I think eventually we’ll get to a point where we won’t have to think about memory management anymore but we aren't really there…

I originally came to Java because of the better performance it offered compared to C++ in large programs . The JVM is specifically designed to remove some of the fundamental performance overheads that low-level languages suffer from, and manifest especially when programs grow large (and a browser is quite large). So when someone talks to me about "GC languages" being slow and low-level languages being fast, I know th…

I don't think it's true that Java offers strictly more optimisation opportunities than low-level languages, but rather different optimization opportunities. C++ and Rust have other opportunities that Java does not generally have:

- Explicit object lifetime and deterministic destruction.

- Stack allocation by default.

- Value types and direct embedding of values in data structures.

- Precise control over data layout, alignment, padding, and SIMD-friendly representations.

- Explicit allocation strategies: arenas, pools, slab allocators, region allocators, custom allocators, memory mapping, etc.

- No mandatory tracing, write barriers, object headers, or garbage-collector scheduling.

- Native interoperation without an FFI boundary.

- More predictable latency behavior.

- Compile-time specialization through templates in C++ and monomorphized generics in Rust.

Rust’s ownership and borrowing model can also provide strong non-aliasing and mutability guarantees in safe code which are useful for optimization.

Saying that "Low-level languages sacrifice performance for control" is also not true imo, since they can avoid allocation entirely, store data contiguously rather than as individually allocated objects, avoid all gc work, control cache behavior and eliminate pointer chasing, and importantly, guarantee hard or soft latency bounds.

Saying that "Most virtual calls in Java are faster than many static calls in C" is not a meaningful claim either. I think? Cuz "it depends" :)

And remember that GC is not free. Objects must eventually be traced. Reference writes may require write barriers. Objects have headers and alignment overhead. Heap size must often be larger to maintain throughput. Concurrent collectors consume CPU and memory bandwidth. Stop-the-world phases or other latency issues remain even with modern collectors. Object movement can complicate native interoperability and pinning. Malloc can cause performance issues but Java is not beating an arena allocator in C++ or Rust.

Keep in mind speed and throughput are not the only performance metrics. So is startup time and memory footprint, where Java loses badly here.

I wish we had real published research to go off of here but real world examples are all we really have. I'm not seeing AAA game studios building their engines in Java. I don't see any OS's building their kernel (or anything really) in Java. If Java is faster than low level languages, why is that?

And look, I don't dislike Java or the JVM, and I'm actually a really big fan of C#. I just like Rust more.

Re: Zig's Incremental Compilation Internals

#149

Earlier quoted context omitted.

> GC languages are slower This is not necessarily true. It depends on a language, e.g. Go is slow, Nim[0] is extremely fast with conventional GC and slightly faster with ARC/ORC[1]. GC programs can be faster than manually managed ones in some cases. It's just manual memory management gives you more control of where and when free is called. And a good type system is a privelege that gives Nim more control with destruc…

You can always use things like arenas in C and get similar speed ups without GC overhead. If you know your memory lifetimes in advanced, avoiding granular malloc/free calls is pretty straightforward. A GC language doesn’t usually offer such options.

[flagged]

Re: Zig's Incremental Compilation Internals

#150

Earlier quoted context omitted.

"two things are within an order of magnitude, and two other things are within an order of magnitude, and those two groups are three orders of magnitude apart" does sound like two groups to me.

> those two groups are three orders of magnitude apart They aren't necessarily, though. Supposing that Zig were "10 issues per MLoC" (with just as much handwaving as the original poster), it would be equidistant from Rust and C. Java may also be more than one order of magnitude away from Rust; we say ~0 but is it 0.01, 0.001, 0.0001...? And why is "1 issue per MLoC" the acceptable metric that delineates what constitu…

You’re making an assumption based on zero information in a very favorable to zig way. When you have no information it’s best to rely on good priors grounded in what you do know.

zig as a language not distinguishing between safe and unsafe. Zig does not forbid unsafe. Zig’s safety model is conceptually not too different from running with ASAN for C/C++ during development. Given that’s already a followed “best practice” for the data that was used to come up with the vulnerability estimate per MLoC for C and C++ it’s reasonable to assume zig is closer to that side (at scale) than to Rust. You could argue defer as a keyword is worth a 10x improvement but even then im not sure how considering c and c++ are close and c++ does essentially a similar thing

Post reply on HN