upvote
Just like every submission about C/C++ gets a comment about how great Rust is, every submission about Rust gets a comment about how great Zig is. Like a clockwork.

Edit: apparently I am replying to the main Zig author? Language evangelism is by far the worst part of Rust and has likely stirred up more anti Rust sentiment than “converting” people to Rust. If you truly care for your language you should use whatever leverage you have to steer your community away from evangelism, not embrace it.

reply
It's unlikely that anyone was going to use Rust anyway but decided not to because they got too annoyed hearing about it.
reply
If you can't be proud about a programming language you made what is even the point?
reply
Neat, I guess?

This comment would be a lot better if it engaged with the posted article, or really had any sort of insight beyond a single compile time metric. What do you want me to take away from your comment? Zig good and Rust bad?

reply
I think the most relevant thing is that building a simple website can (and should) take milliseconds, not minutes, and that -- quoting from the post:

> A brief note: 50 seconds is fine, actually!

50 seconds should actually not be considered fine.

reply
As you've just demonstrated, that point can be made without even mentioning Zig, let alone copy/pasting some compile time stuff with no other comment or context. Which is why I thought (well, hoped) there might be something more to it than just a dunk attempt.

Now we get all of this off-topic discussion about Zig. Which I guess is good for you Zig folk... But it's pretty off-putting for me.

whoisyc's comment is extremely on point. As the VP of community, I would really encourage thinking about what they said.

reply
> As you've just demonstrated, that point can be made without even mentioning Zig, let alone copy/pasting some compile time stuff with no other comment or context. Which is why I thought (well, hoped) there might be something more to it than just a dunk attempt.

Having concrete proof that something can be done more efficiently is extremely important and, no, I haven't "demonstrated" anything, since my earlier comment would have had way less substance to it without the previous context.

The comment from Andrew is not just random compiler stats, but a datapoint showing a comparable example having dramatically different performance characteristics.

You can find in this very HN submission various comments that assume that Rust's compiler performance is impossible to improve because of reasons that actually are mostly (if not entirely) irrelevant. Case in point, see people talking about how Rust compilation must take longer because of the borrow checker (and other safety checks) and Steve pointing out that, no, actually that part of the compilation pipeline is very small.

> Now we get all of this off-topic discussion about Zig.

So no, I would argue the opposite: this discussion is very much on topic.

reply
I disagree. Zig and go are perfect frames of reference to say “actually no, Rust really is slow. Here are examples for you to go and see for yourself”
reply
@AndyKelley I'm super curious what you think the main factors are that make languages like Zig super fast at compiling where languages like Rust and Swift are quite slow. What's the key difference?
reply
I'm not Andrew, but Rust has made several language design decisions that make compiler performance difficult. Some aspects of compiler speed come down to that.

One major difference is the way each project considers compiler performance:

The Rust team has always cared to some degree about this. But, from my recollection of many RFCs, "how does this impact compiler performance" wasn't a first-class concern. And that also doesn't really speak to a lot of the features that were basically implemented before the RFC system existed. So while it's important, it's secondary to other things. And so while a bunch of hard-working people have put in a ton of work to improve performance, they also run up against these more fundamental limitations at the limit.

Andrew has pretty clearly made compiler performance a first-class concern, and that's affected language design decisions. Naturally this leads to a very performant compiler.

reply
> Rust has made several language design decisions that make compiler performance difficult

Do you have a list off the top of your head/do you know of a decent list? I've now read many "compiler slow" thoughtpieces by many people and I have yet to see someone point at a specific feature and say "this is just intrinsically harder".

I believe that it likely exists, but would be good to know what feature to get mad at! Half joking of course

reply
You can have your house built fast, cheap, or well. Pick two; or a bit of all three that adds up to the same effort required. You can't have all three.

You can't have a language with 100% of the possible runtime perf, 100% of the possible compile speed and 100% of the possible programmer ease-of-use.

At best you can abuse the law of diminishing returns aka the 80-20 rule, but that's not easy to balance and you run the risk of creating a language that's okay at everything, but without any strong selling points, like the stellar runtime performance Rust is known for.

So a better way to think about it is: Given Rust's numerous benefits, is having subpar compilation time really that big of a deal?

reply
> Given Rust's numerous benefits, is having subpar compilation time really that big of a deal?

As someone who uses Rust as a daily driver at work at zed.dev (about 600K LoC of Rust), and Zig outside of work on roc-lang.org (which was about 300K LoC of Rust before we decided to rewrite it in Zig, in significant part because of Rust's compilation speed), yes - it is an absolutely huge deal.

I like a lot of things about Rust, but its build times are my biggest pain point.

reply
Rust heavily uses value types with specialized generics, which explodes the work needed by the compiler. It can - sometimes - improve performance. But it always slows down compilation.
reply
Brian Anderson wrote up his thoughts here, and it's a good intro to the topic: https://www.pingcap.com/blog/rust-compilation-model-calamity...

Let's dig into this bit of that, to give you some more color:

> Split compiler/package manager — although it is normal for languages to have a package manager separate from the compiler, in Rust at least this results in both cargo and rustc having imperfect and redundant information about the overall compilation pipeline. As more parts of the pipeline are short-circuited for efficiency, more metadata needs to be transferred between instances of the compiler, mostly through the filesystem, which has overhead.

> Per-compilation-unit code-generation — rustc generates machine code each time it compiles a crate, but it doesn’t need to — with most Rust projects being statically linked, the machine code isn’t needed until the final link step. There may be efficiencies to be achieved by completely separating analysis and code generation.

Rust decided to go with the classic separate compilation model that languages like C use. Let's talk about that compared to Zig, since it was already brought up in this thread.

So imagine we have a project, A, and it depends on B. B is a huge library, 200,000 lines of code, but we only use one function from it in A, and that function is ten lines. Yes, this is probably a bad project management decision, but we're using extremes here to make a point.

Cargo will compile B first, and then A, and then link things together. That's the classic model. And it works. But it's slow: rust had to compile all 200,000 lines of code in B, even though we only are gonna need ten lines. We do all of this work, and then we throw it away at the end. A ton of wasted time and effort. This is often mitigated by the fact that you compile B once, and then compile A a lot, but this still puts a lot of pressure on the linker, and generics also makes this more complex, but I'm getting a bit astray of the main point here, so I'll leave that alone for now.

Zig, on the other hand, does not do this. It requires that you compile your whole program all at once. This means that they can drive the compilation process beginning from main, in other words, only compile the code that's actually reachable in your program. This means that in the equivalent situation, Zig only compiles those ten lines from B, and never bothers with the rest. That's just always going to be faster.

Of course, there are pros and cons to both of these decisions, Rust made the choice it did here for good reasons. But it does mean it's just going to be slower.

reply
Basically, not depending on LLVM or LLD. The above is only possible because we invested years into making our own x86_64 backend and our own linker. You can see all the people ridiculing this decision 2 years ago https://news.ycombinator.com/item?id=36529456
reply
LLVM isnt a good scapegoat. A C application equivalent in size to a rust or c++ application will compile an order of magnitude quicker and they all use LLVM. I'm not a compiler expert, but it doesn't seem right to me that the only possible path to quick compilation for Zig was a custom backend.
reply
Be that as it may, many C compilers are still an order of magnitude faster than LLVM. Probably the best example is tcc, although it is not the only one. C is a much simpler language than rust, so it is expected that compilation should take less time for C. That doesn’t mean llvm isn’t a significant contributor to compilation speed. I believe cranelift compilation of rust is also much faster than the llvm path
reply
> That doesn’t mean llvm isn’t a significant contributor to compilation speed.

That's not what I said. I said it's unlikely that fast compilation cannot be achieved while using LLVM which, I would argue, is proven by the existence of a fast compiler that uses LLVM.

reply
It will compile an order of magnitude quicker because it often doesn't do the same thing - e.g. functions that are aggressively inlined in C++ or Rust or Zig would be compiled separately and linked normally, and generally there's less equivalent of compile-time generics in C code (because you have to either spell out all the instantiations by hand or use preprocessor or a code generator to do something that is two lines of code in C++).
reply
The Rust folks have cranelift and wild BTW. There are alternatives to LLVM and LLD, even though they might not be as obvious to most users.
reply
what is even the point of quoting reactions from two years ago?

this is a terrible look for your whole community

reply
Honestly I think it's good to highlight it. As a industry we're too hampered by "Don't even try that, use the existing thing" and it's causing these end results.
reply
I'm also curious because I've (recently) compiled more or less identical programs in Zig and Rust and they took the same amount of time to compile. I'm guessing people are just making Zig programs with less code and fewer dependencies and not really comparing apples to apples.
reply
Zig is starting to migrate to custom backends for debug builds (instead of using LLVM) plus incremental compilation.

All Zig code is built in a single compilation unit and everything is compiled from scratch every time you change something, including all dependencies and all the parts of the stdlib that you use in your project.

So you've been comparing Zig rebuilds that do all the work every time with Rust rebuilds that cache all dependencies.

Once incremental is fully released you will see instant rebuilds.

reply
When does this land in Zig? Will aarch64 be supported?
reply
When targeting x86_64, the self-hosted backend is already enabled by default on the latest builds of Zig (when compiling in Debug mode). The self-hosted aarch64 backend currently isn't generally usable (so we still default to LLVM when targeting aarch64), but it's likely to be the next ISA we focus on codegen for.
reply
I assume x86_64 is Linux only correct?
reply
Not quite- any ELF or MachO target is enabled by default already. Windows is waiting on some COFF linker bug fixes.
reply
One difference that Zig has is that it doesn't have multiline comments or multiline strings, meaning that the parser can parse any line correctly without context. I assume this makes parallelization trivial.

There is ino operator overloading like C, so A + B can only mean one thing.

You can't redeclare a variable, so foo can only map to one thing.

The list goes on.

Basically it was designed to compile faster, and that means many issues on Github have been getting rejected in order to keep it that way. It's full of compromises.

reply
My non-static Rust website (includes an actual webserver as well as a react-like framework for templating) takes 1.25s to do an incremental recompile with "cargo watch" (which is an external watcher that just kills the process and reruns "cargo run").

And it can be considerably faster if you use something like subsecond[0] (which does incremental linking and hotpatches the running binary). It's not quite as fast as Zig, but it's close.

However, if that 331ms build above is a clean (uncached) build then that's a lot faster than a clean build of my website which takes ~12s.

[0]: https://news.ycombinator.com/item?id=44369642

reply
The 331ms time is mostly uncached. In this case the build script was already cached (must be re-done if the build script is edited), and compiler_rt was already cached (must be done exactly once per target; almost never rebuilt).
reply
Impressive!
reply
Nice. Didn't realize zig build has --watch and -fincremental added. I was mostly using "watchexec -e zig zig build" for recompile on file changes.
reply
New to 0.14.0!
reply
Zig isn’t memory safe though right?
reply
It isn't a lot of things, but I would argue that its exceptionally (heh) good exception handling model / philosophy (making it good, required, and performant) is more important than memory safety, especially when a lot of performance-oriented / bit-banging Rust code just gets shoved into Unsafe blocks anyway. Even C/C++ can be made memory safe, cf. https://github.com/pizlonator/llvm-project-deluge

What I'm more interested to know is what the runtime performance tradeoff is like now; one really has to assume that it's slower than LLVM-generated code, otherwise that monumental achievement seems to have somehow been eclipsed in very short time, with much shorter compile times to boot.

reply
> especially when a lot of performance-oriented / bit-banging Rust code just gets shoved into Unsafe blocks anyway. Even C/C++ can be made memory safe, cf.

Your first claim is unverifiable and the second one is just so, so wrong. Even big projects with very talented, well-paid C or C++ devs eventually end up with CVEs, ~80% of them memory-related. Humans are just not capable of 0% error rate in their code.

If Zig somehow got more popular than C/C++, we would still be stuck in the same CVE bog because of memory unsafety. No thank you.

reply
> If Zig somehow got more popular than C/C++, we would still be stuck in the same CVE bog because of memory unsafety. No thank you.

Zig does a lot of things to prevent or detect memory safety related bugs. I personally haven't encountered a single one so far, while learning the language.

> ~80% of them memory-related.

I assume you're referencing the 70% that MS has published? I think they categorized null pointer exceptions as memory safety bugs as well among other things. Zig is strict about those, has error unions, and is strict and explicit around casting. It can also detect memory leaks and use after free among other things. It's a language that's very explicit about a lot of things, such as control flow, allocation strategies etc. And there's comptime, which is a very potent tool to guarantee all sorts of things that go well beyond memory safety.

I almost want to say that your comment presents a false dichotomy in terms of the safety concern, but I'm not an expert in either Rust or Zig. I think however it's a bit broad and unfair.

reply
> Even C/C++ can be made memory safe, cf. https://github.com/pizlonator/llvm-project-deluge

> Fil-C achieves this using a combination of concurrent garbage collection and invisible capabilities (each pointer in memory has a corresponding capability, not visible to the C address space)

With significant performance and memory overhead. That just isn't the same ballpark that Rust is playing in although hugely important if you want to bring forward performance insensitive C code into a more secure execution environment.

reply
Fil-C has advanced a lot since I last looked at it:

> Fil-C is currently 1.5x slower than normal C in good cases, and about 4x slower in the worst cases.

with room for optimization still. Compatibility has improved massively too, due to big changes to how it works. The early versions were kind of toys, but if Filip's claims about the current version hold up then this is starting to look like a very useful bit of kit. And he has the kind of background that means we should take this seriously. There's a LOT of use cases for taking stuff written in C and eliminating memory safety issues for only a 50% slowdown.

reply
How confident are you that memory safety (or lack thereof) is a significant variable in how fast a compiler is?
reply
Zig is less memory safe than Rust, but more than C/C++. Neither Zig nor Rust is fundamentally memory safe.
reply
What? Zig is definitively not memory-safe, while safe Rust, is, by definition, memory-safe. Unsafe rust is not memory-safe, but you generally don't need to have a lot of it around.
reply
Safe Rust is demonstrably not memory-safe: https://github.com/Speykious/cve-rs/tree/main
reply
This is a compiler bug. This has no bearing on the language itself. Bugs happen, and they will be fixed, even this one.
reply
It's a 10 year old bug which will eventually be fixed but may require changes to how Rust handles type variance.

Until you guys write an actual formal specification, the compiler is the language.

reply
It’s a ten year old bug because it has never been found in the wild, ever, in those ten years. Low impact, high implementation effort bugs take less priority than bugs that affect real users.

The project is adopting Ferrocene for the spec.

reply
Ferrocene is intended to document the behavior of the current version of the rustc compiler, so it's just an effort to formalize "the compiler is the language".

Yes, the soundness hole itself is low impact and doesn't need to be prioritized but it undermines the binary "Zig is definitively not memory-safe, while safe Rust, is, by definition, memory-safe" argument that was made in response to me. Now you're dealing with qualitative / quantitative questions of practical impact, in which my original statement holds: "Zig is less memory safe than Rust, but more than C/C++. Neither Zig nor Rust is fundamentally memory safe."

You can of course declare that Safe Rust is by definition memory safe, but that doesn't make it any more true than declaring that Rust solves the halting problem or that it proves P=NP. RustBelt is proven sound. Rust by contrast, as being documented by Ferrocene, is currently fundamentally unsound (though you won't hit the soundness issues in practice).

reply
I believe these two statements should show the fundamental difference:

- If a safe Rust program exhibits a memory safety problem, it is a bug in the Rust compiler that is to be fixed - If a Zig program exhibits a memory safety problem, it is a bug in the Zig program that needs to be fixed, not in the compiler

Wouldn't you agree?

> Ferrocene is intended to document the behavior of the current version of the rustc compiler, so it's just an effort to formalize "the compiler is the language".

I must admit I haven't read the specification, but I doubt they attempt to be "bug for bug" compatible in the sense that the spec enumerates memory safety bugs present in the Rust compiler. But am I then mistaken?

reply
No, I don't agree. A compiler bug is something that gets fixed in a patch release after it's reported, or perhaps some platform-specific regression that gets fixed in the next release after it's reported. What we're discussing by contrast is a soundness hole in the language itself - one which will most likely require breaking changes to the language to close (i.e. some older programs that were perfectly safe will fail to compile as a side effect of tightening up the Rust language to prevent this soundness hole).

As to the Ferrocene specification, it explicitly states "Any difference between the FLS and the behavior of the Rust compiler is considered an error on our part and the FLS will be updated accordingly."

Proposals to fix the soundness hole in Rust either change the variance rules themselves, or require where clauses in certain places. Either of these changes would require corresponding changes to chapter 4 of the Ferrocene specification.

reply
> As to the Ferrocene specification, it explicitly states "Any difference between the FLS and the behavior of the Rust compiler is considered an error on our part and the FLS will be updated accordingly."

Right, this is from before it's adopted as the actual spec, because it was from outside the project, and so could not be.

Also, these goalposts are moving: it was "Rust doesn't have a spec" and now it's "I don't like the spec."

Fixing this soundness hole does not require a breaking change to the language. It is an implementation bug, not a problem with the language as specified. But even if it were, Rust's policies around soundness do allow for this, and the project has done it in the past.

reply
The goalposts haven't moved. The goalposts were always "the current compiler is the language".

If there is a proposed fix to the soundness hole that wouldn't reject some existing sound Rust code, please link to it; none of the proposed fixes I've seen do so. And yes, Rust's policies do allow for breaking changes in pursuit of soundness - likely some day many years from now safe Rust will indeed be sound and guaranteed to be memory safe.

reply
And Rust has and will make those breaking changes, while Zig will likely not. In fact there are documented and blessed ways to break memory safety in Zig, and no one is calling them soundness bugs!

I really don’t see how you can claim with a straight face that the two approaches are the same.

reply
"In fact there are documented and blessed ways to break memory safety in Zig" - just as there are in Rust... even the Rust standard library makes liberal use of them (thereby making any program which invokes those parts of the standard library transitively unsafe by definition).

Look, I'm not saying the Zig and Rust approaches are the same. I explicitly stated that Rust is more memory safe than Zig (which is in turn more memory safe than C/C++).

This is because Rust has clearly delineated a "safe" subset of Rust which you have to explicitly opt out of that is mostly sound (and has a goal of eventually being entirely sound), has a culture of encouraging the use of the safe subset, and has taken a good approach to the interfacing of safe and unsafe code (i.e. if unsafe code is properly written and satisfies the exposed contract - despite the compiler being unable to verify this - then safe code can safely be linked with it).

All of this results in extremely low risk of memory corruption for Rust programs in practice (far lower than any other commonly used non-GC language with the sole exception of SPARK).

What you can't do though is reject the notion of memory safety being a sliding scale and draw a binary distinction between languages that are 100% perfectly memory safe and languages that are memory unsafe. Well you can, but Rust will fall on the side of memory unsafe for many years to come. Java (ignoring vendor-specific extensions) falls on the safe side though - the language semantics as specified are sound and it doesn't even have an unsafe subset.

reply
> If a safe Rust program exhibits a memory safety problem, it is a bug in the Rust compiler that is to be fixed - If a Zig program exhibits a memory safety problem, it is a bug in the Zig program that needs to be fixed, not in the compiler

That is the absolute best description of memory safety I’ve heard expressed.

reply
deleted
reply
The second you have any `unsafe`, Rust is _by definition_ not memory-safe.
reply
By that definition, Python is not memory-safe, Java is not memory-safe, Go is not memory-safe, and so on. All of these languages contain escape hatches to do memory-unsafe stuff, yet no one is calling them memory unsafe.
reply
Go is more memory unsafe than Java or Rust. Data races in concurrent Go code can cause memory corruption, unlike in concurrent Java code. Safe Rust is designed to avoid data races altogether using static analysis.
reply
And the majority of the Rust standard library uses `unsafe`.
reply
Prove it. Show me the stats that the standard library is over 50% unsafe.
reply
By definition yes. There were a lot of lies to persuade managers. You can write a lot into your documentation.

But by implementation and spec definitely not.

reply
deleted
reply
Zig is a small and simple language. It doesn't need a complicated compiler.

Rust is a large and robust language meant for serious systems programming. The scope of problems Rust addresses is large, and Rust seeks to be deployed to very large scale software problems.

These two are not the same and do not merit an apples to apples comparison.

edit: I made some changes to my phrasing. I described Zig as a "toy" language, which wasn't the right wording.

These languages are at different stages of maturity, have different levels of complexity, and have different customers. They shouldn't be measured against each other so superficially.

reply
This is an amusing argument to make in favor of Rust, since it's exactly the kind of dismissive statement that Ada proponents make about other languages including Rust.
reply
Come on now. This isn't acceptable behavior.

(EDIT: The parent has since edited this comment to contain more than just "zig bad rust good", but I still think the combative-ness and insulting tone at the time I made this comment isn't cool.)

reply
> but I still think the combative-ness and insulting tone at the time I made this comment isn't cool

Respectfully, the parent only offers up a Zig compile time metric. That's it. That's the entire comment.

This HN post about Rust is now being dominated by a cheap shot Zig one liner humblebrag from the lead author of Zig.

I think this thread needs a little more nuance.

reply
> Respectfully, the parent only offers up a Zig compile time metric. That's it. That's the entire comment.

That's correct, but slinging cheap shots at each other is not how discussions on this site are supposed to be.

> I think this thread needs a little more nuance.

Yes, but your comment offers none.

reply
FWIW, I think your revised comment is far better, even though I disagree with some of the framing, there's at least some substance there.

Being frustrated by perceived bad behavior doesn't mean responding with more bad behavior is a good way to improve the discourse, if that's your goal here.

reply
You're 100% right, Steve. Thank you for your voice of moderation. You've been amazing to this community.
reply
It's all good. I'm very guilty of bad behavior myself a lot of the time. It's on all of us to give gentle nudges when we see each other getting out of line. I deserve to be told the same if you see me doing this too!
reply