Rust vs C++ & Go: Surprising Performance, Memory Safety & Development Speed
This article examines Rust’s performance advantages over C++ and Go through benchmark tests on prime number calculations, binary size, runtime speed, memory and CPU usage, and explains Rust’s ownership, borrowing, lifetimes, and concurrency model that provide memory safety without sacrificing efficiency.
Introduction
When choosing a programming language, developers must balance performance, resource consumption, and development efficiency. Rust stands out by offering high performance, low memory overhead, and strong safety guarantees, making it an intriguing alternative to C++ and Go.
Performance Comparison
Binary Size
Static binaries produced by Rust, C++, Go, and Python differ significantly. Rust binaries are about 249 KB, C++ 129 KB, Go 1.58 MB, and Python 3.88 MB. The conclusion is: Python > Go > Rust > C++ in binary size.
Runtime Speed
Using a prime‑number search (finding all primes below 10,000,000) as a test, Rust consistently outperformed the other languages. In multiple runs across three machines, Rust’s iteration count per minute was higher than C++, which in turn beat Go and Python. The conclusion: Rust > C++ > Go > Python.
Rust’s efficiency even surpasses C++ in some scenarios.
Memory Consumption
Rough measurements show Rust uses about 30 MB, C++ 2.2 MB, Go 124 MB, and Python 190 MB. The ranking is: Python > Go > Rust > C++.
CPU Usage
CPU usage percentages were roughly 12.5 % for both Rust and C++, 24 % for Go, and 13 % for Python, leading to the conclusion: Go > Python > Rust = C++.
Memory Safety
Rust guarantees memory safety without runtime overhead by using an ownership system, borrowing rules, and a strict compile‑time borrow checker. These mechanisms prevent common bugs such as null‑pointer dereferences, use‑after‑free, data races, and dangling references.
Ownership Rules
let obj = String::from("hello");The variable obj owns the String. Ownership can be transferred, and when the owner goes out of scope the value is automatically dropped.
fn main() {
let s = String::from("hello");
let s1 = s; // ownership moves to s1
// println!("{}", s); // error: s is no longer valid
}Borrowing Rules
References allow temporary access without taking ownership. Immutable references are the default; mutable references require exclusive access.
fn test(s1: &String) {
println!("{}", s1);
}
fn main() {
let s = String::from("hello");
test(&s); // borrow immutably
println!("{}", s); // s is still valid
}Attempting to modify an immutable borrow results in a compile‑time error. Using &mut creates a mutable borrow, which must be unique within its scope.
Lifetime Rules
Every reference has a lifetime that must not exceed the lifetime of the value it points to. The compiler enforces that references never outlive their owners, preventing dangling pointers.
{
let r; // 'a
{
let x = 5; // 'b
r = &x; // error: 'b does not live long enough
}
println!("r: {}", r);
}Concurrency Safety
Rust’s type system ensures data races cannot occur. Threads must own the data they use, or share it via thread‑safe primitives such as Arc and Mutex.
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Here’s a vector: {:?}", v);
});
handle.join().unwrap();
}When a closure captures a variable, the compiler requires the move keyword or a thread‑safe reference. For shared mutable state, Arc<Mutex<T>> is used.
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for h in handles { h.join().unwrap(); }
println!("Result: {}", *counter.lock().unwrap());
}Development Efficiency
While Rust’s steep learning curve and strict compiler can slow initial development, the guarantees it provides reduce debugging time dramatically. Once code compiles, memory‑related bugs are largely eliminated.
Cross‑Platform Support
Rust can produce static binaries for Windows, Linux, macOS, ARM, and many other targets, simplifying deployment across diverse environments. It also supports embedded development.
Ecosystem
Rust’s ecosystem is younger than that of Python or Go, but it is growing rapidly, with many popular crates available and increasing community adoption.
Conclusion
Rust delivers high performance comparable to C++, superior memory safety without garbage collection, robust concurrency guarantees, and excellent cross‑platform capabilities. For developers seeking a language that combines efficiency with safety, Rust is a compelling choice.
Benchmark Images
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
