DEV Community

Alice Turner
Alice Turner

Posted on

Rust vs Zig Error Handling

Recently, I’ve been considering whether Zig might be a better fit for developing a game engine due to its focus on simple code, transparent control flow, and control over allocations. Zig resembles C in its bare-bones approach, requiring programmers to manually build their structures and algorithms.

My programming philosophy is to keep things basic and minimal. Over-abstraction can lead to less intuitive and bloated code. When I first heard about Zig, I was excited to try it out. However, I felt it needed more time to mature, so I set it aside for a while.

In the meantime, I’ve been refining my understanding of Rust, a language I started learning at the beginning of 2023. I read the 2021 edition of “The Rust Programming Language” book, which I purchased to support the authors. I’m glad I did, as it provided a solid foundation in the language.

Since then, I’ve been developing hobby projects in Rust and supplementing my knowledge with additional books. As Zig gains traction, I’ve heard claims that it’s faster than C and other positive comments. So, I decided to put some of these claims to the test.

First, I tested the assertion that Zig’s general-purpose allocator (GPA) is faster than Rust’s, which uses libc on Linux and the Microsoft Visual C Runtime (MSVCRT) allocator. I wrote applications in both languages that looped over a function 10 times, each time running an allocation 100,000 times, assigning “hello world” to the allocation, and then exiting the function. According to my test, Rust was 1.89 seconds faster than Zig using the GPA. Both applications were built using their respective release modes. I don’t fully understand the resulting assembly of the Rust application, but it seems that heap allocations are optimized away. This might not be the best test since the Rust application isn’t doing the same as the Zig application, which explicitly requests a heap allocation.

Another important aspect is error handling. Zig uses a union type for errors, while Rust can use an integer type, dynamic allocation, and dynamic dispatch, either statically or in a hybrid approach. Initially, I liked Zig’s approach because it seemed to avoid slowing down error handling. However, I decided to test my Rust skills and developed different ways of handling errors, eventually settling on a hybrid approach.

In Zig, providing dynamic errors involves using a string allocation, as the bytes need to live past the stack frame they are allocated on. This requires dynamic sizing since the contents may change at runtime. Zig follows the rules of computer science but avoids hidden allocations, making them obvious when programmer.

In contrast, Rust’s standard library uses the Box type, which involves dynamic dispatch and a heap allocation. These allocations are limited to when the .into() method is called on an error or the ::new method is invoked. These calls are rare, and most uses of errors in the standard library are static strings stored in the binary.

In conclusion, Zig and Rust take different approaches to error handling. Neither approach is wrong; both are valid. Zig results in smaller binary sizes with predictable control flow, while Rust generally produces larger binaries with compile-time optimizations that make the resulting binary more of a black box. Rust requires more understanding and is more opinionated, but over time, it offers more control and flexibility, leading to hybrid approaches.

I’ve tried to be as fair as possible. Both languages have their strengths and weaknesses. I recommend both languages: I’m encouraging my son to learn Zig for its simplicity, but for production and scalability, I prefer Rust for its expressiveness and optimizations.

I hope this helps people assess the differences between Rust and Zig. Best of luck on your programming journey!

Top comments (7)

Collapse
 
eljayadobe profile image
Eljay-Adobe • Edited

Zig latest release 0.13.0. I read that as Zig does not consider itself to be "1.0" yet. Under construction. It's still undergoing evolution, churn, possible breaking changes to the language itself.

Rust latest release 1.79.0. I read that as Rust has reached a milestone of stability.

I consider the stability to be an important consideration. Not the only one, but I do much prefer "1.0" languages over alpha or beta languages for non-toy projects.

Collapse
 
fluffy-soft-dev profile image
Alice Turner

1 thing i love about Zig is the community. I love the concept of the language, and admire it. Contrasted with the Rust community, well we all know it's reputation. Even though i've decided not use Zig, i really want to watch what it becomes and i hope it does well :)

Collapse
 
martinbaun profile image
Martin Baun

Great writeup, it's important to learn C first.

Collapse
 
fluffy-soft-dev profile image
Alice Turner

I offered to buy my son a book on C explaining to him that it is 1 level up from assembly, it obfuscates anything to do with the CPU but memory is manual. However, C doesn't have a mascot and he's only 14, the Ziguana got him piqued for Zig 🥲 but I do agree C is probably the best place to start

Collapse
 
eljayadobe profile image
Eljay-Adobe

I taught my kids Python first. I thought that was a good language to start with.

If not Python, I probably would've turn to Lisp because it's syntax is very simple and very regular. (And then I'd pull out the SICP/2e and start from there.)

Collapse
 
tylerlwsmith profile image
Tyler Smith

Congrats on the first post! It's an interesting read: I haven't used Zig or Rust but I keep hearing about them so it's super cool to hear the mechanics of using them

Collapse
 
mellen profile image
Matt Ellen-Tsivintzeli • Edited

Thanks for the thoughtful comparison