Rust Studio/Why Rust

Why choose Rust

Measured on one PC with scripts you can run yourself, including where Rust is not the best choice.

This page compares Rust with five other languages on the same three small programs, then looks at the bugs each language lets through. Every number was measured on one PC and is regenerated by scripts in the benchmarks folder of the Ruststudio source, so you can run them yourself.

  • Machine: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz, 12 logical cores, Windows NT 10.0.26200.0
  • Versions: rustc 1.93.0 (254b59607 2026-01-19); go version go1.26.5 windows/amd64; .NET 10.0.302; openjdk version "17.0.18" 2026-01-20; Node 22.19.0; Python 3.13.7
  • Method: each program is run 3 times at below-normal priority, one after another; the table shows the median time and the peak memory of the process. Start-up time is included, so the Java and C# figures contain starting their runtime. Every program prints a checksum, and all six languages print the same one (165197 points inside the Mandelbrot set, 1,270,607 primes, 50,000 different words with a most common count of 96), so they all did the same work.
  • Not measured: C and C++ (no compiler is installed on this PC) and anything on other hardware. These are small programs: a real application mixes many kinds of work, so treat the figures as an illustration of trade-offs, not as a verdict.

1. Speed

Time in seconds (lower is better)RustGoC#JavaNodePythonRust, fast hasher
Mandelbrot (floating point, 800 x 800)0.090.090.170.180.152.74-
Prime sieve (memory and tight loops, primes below 20 million)0.160.180.230.240.261.15-
Word count (hash map and strings, 3 million words)0.810.430.470.550.601.710.75

What the numbers say:

  • On the two number-crunching programs Rust and Go lead: Rust took 0.09 s on the Mandelbrot set and 0.16 s on the sieve. C#, Java and Node were 1.7 to 2.0 times slower on the Mandelbrot set (much of that is starting their runtimes), and Python was 30 times slower on the Mandelbrot set and 7 times slower on the sieve, although its sieve leans on fast built-in code.
  • Rust is not automatically the fastest. On the word count, which makes millions of small strings and looks each one up in a hash map, Go (0.43 s) and C# (0.47 s) beat Rust (0.81 s). Rust's default hash map uses a deliberately attack-resistant hash and the program uses the system allocator, which is slower than the allocators built into Go and .NET for many tiny objects. A fast hasher helped only a little (0.75 s), so most of the cost is allocation. Rust gives you the control to fix that (reuse buffers, avoid the allocation, choose another allocator); it does not do it for you.

2. Memory

Peak memory in MB (lower is better)RustGoC#JavaNodePython
Mandelbrot (floating point, 800 x 800)3.95.621.038.030.710.7
Prime sieve (memory and tight loops, primes below 20 million)23.025.539.655.847.948.8
Word count (hash map and strings, 3 million words)8.013.035.399.149.516.2

Rust used the least memory in all three programs, for example 3.9 MB on the Mandelbrot set and 8.0 MB on the word count (against 99 MB for Java, whose runtime reserves memory for its collector). There is no garbage collector in a Rust program, so memory is returned the moment a value goes out of scope, and there are no pauses while a collector runs.

3. Size of what you ship

LanguageWhat the benchmark program turns intoNeeds on the PC
Rustone executable, 146 KBnothing else installed
Goone executable, 2.4 MB (it carries its runtime)nothing else installed
C#a 6 KB assemblythe .NET runtime
Javaa 3 KB class filea Java runtime
Node, Pythonthe source fileNode or Python, plus their packages

4. How much code

LanguageRustGoC#JavaNodePython
Lines (without blank lines and comments)836861514641

Rust is more wordy than Python or Node (83 lines against 41 and 46; the Rust figure includes about 30 lines for the fast-hasher experiment). You write the types, and in return the compiler checks them.

5. Bugs that are caught before the program runs

The same small bug in each language, and what happened when the program was built and run.

The bugRustGoC#JavaNodePython
A missing value used as if it were therecompile errorcrash when runcrash when runcrash when runcrash when runcrash when run
Use of a value after it was moved or freedcompile errornot possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)
A reference that outlives what it points tocompile errornot possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)not possible (a garbage collector keeps it alive)
Eight threads adding to one counter, no lockcompile error244,043 (silently wrong)207,098 (silently wrong)117,040 (silently wrong)800,000800,000
i32 maximum plus onepanics in a debug build, wraps in a release buildwraps silently to -2,147,483,648wraps silently to -2,147,483,648wraps silently to -2,147,483,648numbers are doubles: no wrapintegers do not overflow

Reading the table:

  • Rust refuses the first four programs: the compiler reports what is wrong (E0599 no such method on an Option, E0382 use of moved value, E0515 returning a reference to a local, a lifetime error for the unlocked counter) and no executable is made. The version of the counter that compiles uses an atomic and prints the right total, 800,000.
  • In Go, C# and Java the unlocked counter compiles, runs and prints a wrong total with no warning, and a different wrong total each time. Go has a race detector (go run -race) that finds it when you remember to use it; the others need tools or review.
  • Node runs your code on one thread, so this race cannot happen there. Python's global lock hid it in this run (it printed 800,000), which is luck of scheduling and not a guarantee.
  • A missing value is a crash at run time in every other language (NullReferenceException, NullPointerException, TypeError, a nil pointer panic). Rust has no null: a value that may be absent is an Option, and the compiler makes you handle the empty case.
  • Integer overflow is the one that Rust does not stop: a debug build panics, but a release build wraps like the others (use checked_add or wrapping_add to say what you mean). Python has no overflow because its integers grow.

6. Memory leaks: Rust does not make them impossible

A leak is memory that is never given back. Two objects that point at each other were made and dropped two million times:

LanguageRustGoC#JavaNodePython
Peak memory in MB43213273393112
  • In Rust the cycle is never freed: reference counting cannot free a cycle, so the program grew to 432 MB and would keep growing. Rust makes use-after-free and double free impossible in safe code; it does not promise there are no leaks. The fix is to break the cycle with a Weak reference, and it is a habit you have to learn.
  • Go, C#, Node and Python collect cycles, and stayed at 13 to 31 MB. Java also collected them; its 339 MB peak is the size the runtime chose for its heap, not a leak.
  • A cache that is never emptied leaks in every language. No language fixes that for you.

7. What others have published

These are published figures from large projects; check the original posts before you rely on them.

  • Microsoft's security team reported (2019) that about 70 percent of the security vulnerabilities it fixes each year are memory safety bugs.
  • The Chromium project reported (2020) that around 70 percent of its serious security bugs are memory safety problems.
  • Google reported (2024) that as Android moved new code to memory-safe languages, the share of memory-safety vulnerabilities fell from 76 percent of the total in 2019 to 24 percent in 2024.

Memory safety bugs are the kind Rust's compiler removes from safe code.

8. What Rust costs

  • Learning time. Ownership and lifetimes are new to most people; expect weeks before they feel natural. The compiler's messages are unusually helpful, and the IDE shows them as you type.
  • Compile time. Release builds are slower than in Go or C#. Ruststudio's Cargo Cleaner and incremental builds help; the first build of a big project still takes minutes.
  • Ecosystem. crates.io is large and growing, but some areas (mature desktop GUI toolkits, some enterprise libraries) are thinner than in Java, .NET or JavaScript. That is what the rupm registry and the first-party packages are for.
  • Wordiness. More code than Python or Node for the same job, as the table shows.
  • Not automatic speed. As the word count showed, fast Rust code is written, not assumed.

9. Is Rust right for your project?

Choose Rust when:

  • a crash, a security hole or a wrong answer is expensive (servers on the internet, parsers of untrusted data, finance, devices);
  • you need predictable speed and memory without a garbage collector's pauses (latency-sensitive services, games, embedded, tools);
  • you want one small executable to hand to users, or the same core code on Windows, macOS, Linux, the web (WebAssembly) and phones;
  • the code will live for years and be changed by many people: the compiler keeps checking what reviewers would otherwise have to.

Choose something else when:

  • the program is a throw-away script or a quick data exploration (Python is faster to write);
  • the work is mostly gluing existing services and a team already knows Java or .NET well and the hot path is not performance-critical;
  • you need a library that only exists in another ecosystem.

A sensible way to adopt Rust:

  1. Pick one small, contained piece: a command-line tool, a service endpoint, a parser, a hot loop (as a library called from the old code).
  2. Start from a sample in Ruststudio (New Project > Samples), turn on clippy and format-on-save, and keep tests next to the code.
  3. Measure before and after with your own workload, the way benchmarks/ does.
  4. Grow from there, and keep the parts that are not worth rewriting.