Hello Rust Community!
I have some experience in writing go code and now learning rust. I know there are lot of comparison everywhere, but to benchmark both languages with very high concurrency I wrote a small piece of code in both Rust using tokio and in Golang. I does nothing just spawns bunch of goroutines and tokio tasks and exist after waiting 10 s. I set both programs to use equal threads. Here is my code:
Go:
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
for i := 0; i < 1_000_000; i++ {
wg.Add(1)
go worker(i)
}
wg.Wait()
fmt.Println("done")
}
func worker(i int) {
time.Sleep(10 * time.Second)
fmt.Println(i)
wg.Done()
}
Rust:
use std::time::Duration;
use tokio::task::JoinSet;
async fn process_one(i: i32) {
tokio::time::sleep(Duration::new(10, 0)).await;
println!("{}", i);
}
#[tokio::main(flavor = "multi_thread", worker_threads = 16)]
async fn main() {
let mut set = JoinSet::new();
for i in 0..1_000_000 {
set.spawn(async move {
process_one(i).await;
});
}
set.join_all().await;
println!("done")
}
I compiled Rust code with cargo build --release
I executed both of them:
env GOMAXPROCS=16 /usr/bin/time -v ./routinetestgo
And for rust
/usr/bin/time -v ./routinetestrust
Following is the output:
Go:
Command being timed: "./routinetestgo"
User time (seconds): 17.64
System time (seconds): 7.24
Percent of CPU this job got: 166%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:14.96
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2758548
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 694710
Voluntary context switches: 358359
Involuntary context switches: 3836
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
Rust:
Command being timed: "./routinetestrust"
User time (seconds): 6.54
System time (seconds): 11.62
Percent of CPU this job got: 112%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:16.13
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 377856
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 93967
Voluntary context switches: 1292955
Involuntary context switches: 1101
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
I carried out this execution multiple times but rust code always stays behind (Considering elapsed wall clock time). Is this normal to have such difference?...seems Rust is taking around ~7% more time. Or do I need to optimize rust code further to get comparable results? Can someone please explain the cause of this?