← back to main

My Experience with Rust

Information is subjective.

Why

One of my friends was actively pitching it as new shiny thing i should try. I did not really want to learn new language for nothing, but decided to try Rust after a week of attempts on using C++23 modules (I just wanted faster compile times without headers), which failed completely - bugs literally everywhere, ICEs, documentation so bad that reading source was more useful, and I realized how much time I spend on CMake (and earlier Make - I love slashes btw), dependency management, resolving compiler differences and other non-programming stuff, and thought that maybe Rust could solve that

So, the obvious thing to do was to port my entire C++ Vulkan renderer (almost) line by line without trying to run it once

If you are experienced Rust dev, i would really appreciate code review of my renderer

First impression

Cargo is a build system that I don't think much about. Tooling is amazing: rust-analyzer, clippy, fmt (Rust is the only language where a formatter doesn't annoy me), plus community tools like cargo-asm and lots of others.

This language excites me

  • Enums
  • backtraces
  • built-in checks (out-of-bounds, alignment, overflows / zero-div). I whish they were more optional though
  • No constructors (seriously, there are more constructors in C++ than there are math subjects).
  • Fast std containers
  • built-in tests & benchmarks (#![feature(test)] + black_box makes it soooo easy).
  • Stack slices
  • include_bytes!() (i wish it was auto-aligned)
  • Simple web builds (though you do need --target-cpu=mvp now).
  • Click to see my renderer running in web! (right here)

Blazingly Fast… Sometimes

Performance-wise, Rust is truly a rocket. But not all Rust.

C-like* Rust is a beast. Sticking to references and simple struct hierarchy forces you into code that produces insane assembly. However, wrap everything in Options, Rcs and Boxes, dyn traits and deep nested containers, and it's not so fast anymore.

So far, most Rust code I've seen sticks to one of those two extremes. And there's also a trend to trick the borrow checker - Rcs and Vec[index] as "virtual memory". Is it just me, or do some people praise the borrow checker but then subvert it?

* - a question: am I missing something or is there no way to make math more C-like? I mean something like this but compiler-driven: https://github.com/platonvin/unsafe_math

Some real info

  • my binary sizes went from ~600 KB to ~700 KB - likely due to stack slices (which is good: why heap-allocate if the stack suffices?).
  • Performance-wise nothing really changed: Rust is faster at low opt-levels (precompiled std?), and on highest opt-levels the gap narrows.
  • Compile times actually improved, though both C++ and Rust compile times still hurt iteration speed.

Libraries: The Weak Link

This is kind of a point of failure for me in the Rust ecosystem - there just aren't that many great libraries. initializing OpenGL with winit (whose examples use deprecated code cause they change API every second) and glow is harder than with assembly. Algebra libraries are written by people who dont seem to code at all. Peak frustration was when I couldn't figure out the MagicaVoxel (.vox) parser docs and ended up porting the C++ parser instead (spent less time on that, huh).

In Rust you don't spend a day trying to make a library compile - you spend a day looking for one that doesn't suck. Crates refactor every few months and break APIs for no practical reason. Documentation is often useless (says a lot, explains nothing), and reading source is unreasonably hard because logic is smeared acros dozeon layers of tiny functions (std has better docs (i still dont understand cells, pin and leak()) but sufffers from unreadable source even more. Maybe its just experience, but i feel relatively comfortable reading sources of C/C++ libraries).

Whats next?

Overall, I'm going to use Rust for a while. I don't any other language* offering significant improvements that'd make me switch (but who knows).

I'd like "safe" to be more optional, nicer syntax for "unsafe", first-class SIMD, much faster compile times, and more importantly - simplicity as a language idea, whith library authors aware of it.

I will probably depend less on external crates in future for simplicity.

*I tried Zig, did not like it at all. Maybe I'll like Jonathan Blow language, but my project is not complicated enough to ask for an access.