Rust language is being clamined to be "a system programming language that runs blazingly fast, prevents almost all crashes*, and eliminates data races".
I thought of running same fibonnaci algorithm against Rust to see how blazingly fast is it.
You can find fib.rs source code here on lang-compare on my github. I compared it against fib.go and fib.c
FIBONACCI - 50
Language C (gcc-4.9.1):
gcc-4.9 -O3 fib.c
/usr/bin/time -lp ./a.out 50
LANGUAGE C: 12586269025
real 52.87
user 52.83
sys 0.01
557056 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
163 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
0 voluntary context switches
497 involuntary context switches
Language Go (go1.4beta1 darwin/amd64):
go build fib.go
/usr/bin/time -lp ./fib 50
LANGUAGE GO: 12586269025
real 96.56
user 96.47
sys 0.06
1232896 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
300 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
9010 voluntary context switches
1338 involuntary context switches
Language Rust (0.13.0-nightly (45cbdec41 2014-11-07 00:02:18 +0000)):
/usr/local/bin/rustc --opt-level 3 fib.rs
/usr/bin/time -lp ./fib 50
LANGUAGE Rust: 12586269025
real 101.53
user 101.44
sys 0.01
1040384 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
229 page reclaims
46 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
1 voluntary context switches
914 involuntary context switches
Surprisingly results are as below where CPU usage (real) is as C (52.87) > Go (96.56) > Rust (101.53).
gcc-4.9 -O3 fib.c
/usr/bin/time -lp ./a.out 50
LANGUAGE C: 12586269025
real 52.87
user 52.83
sys 0.01
557056 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
163 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
0 voluntary context switches
497 involuntary context switches
Language Go (go1.4beta1 darwin/amd64):
go build fib.go
/usr/bin/time -lp ./fib 50
LANGUAGE GO: 12586269025
real 96.56
user 96.47
sys 0.06
1232896 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
300 page reclaims
0 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
9010 voluntary context switches
1338 involuntary context switches
Language Rust (0.13.0-nightly (45cbdec41 2014-11-07 00:02:18 +0000)):
/usr/local/bin/rustc --opt-level 3 fib.rs
/usr/bin/time -lp ./fib 50
LANGUAGE Rust: 12586269025
real 101.53
user 101.44
sys 0.01
1040384 maximum resident set size
0 average shared memory size
0 average unshared data size
0 average unshared stack size
229 page reclaims
46 page faults
0 swaps
0 block input operations
0 block output operations
0 messages sent
0 messages received
0 signals received
1 voluntary context switches
914 involuntary context switches
Surprisingly results are as below where CPU usage (real) is as C (52.87) > Go (96.56) > Rust (101.53).
| Language | CPU(real) | Memory(Max resident size) |
| C | 52.87 | 544K |
| Go | 96.56 | 1204K |
| Rust | 101.53 | 1016K |
NOTE: Is there a better way to read command line argument and convert into integer? I felt it was very painful to figure that out.
E.g.
In C language:
long n = atol(argv[1]);
In Go language:
n, _ := strconv.Atoi(os.Args[1])
In Rust language:
let args = os::args(); let args = args.as_slice(); let n :u64 = from_str::<u64>(args[1].as_slice()).unwrap();
E.g.
In C language:
long n = atol(argv[1]);
In Go language:
n, _ := strconv.Atoi(os.Args[1])
In Rust language:
let args = os::args(); let args = args.as_slice(); let n :u64 = from_str::<u64>(args[1].as_slice()).unwrap();