I was reading What is special about Nim, and they have an example to show how Nim is as fast as C by implementing the sieve of Eratosthenes in both languages and comparing the runtimes.

I thought it would be fun to compare Rust, so I tried a naive implementation and couldn’t match the performance. Here are the timings that I got:

Timings (best of 3):

```
> rustc --version
rustc 1.8.0-nightly (18b851bc5 2016-01-22)
> rustc -O test-rs.rs -o test-rs
> time ./test-rs
0
real 0m0.714s
user 0m0.679s
sys 0m0.031s
> nim --version
Nim Compiler Version 0.13.0 (2016-01-22) [MacOSX: amd64]
Copyright (c) 2006-2015 by Andreas Rumpf
git hash: a121c3f9eb2a348b9d6ae03ffd01aab26a238c30
active boot switches: -d:release
> nim c -d:release test.nim
> mv test test-nim
> time ./test-nim
0
real 0m0.554s
user 0m0.519s
sys 0m0.027s
```

Rust source:

```
#![feature(step_by)]
fn eratosthenes(n: i32) -> Vec<i8> {
let mut result: Vec<i8> = vec![0; (n + 1) as usize];
result[0] = 1;
result[1] = 1;
let slimit = (n as f64).sqrt() as usize;
for i in 2..slimit {
if result[i] == 0 {
for j in ((i * i)..n as usize).step_by(i) {
result[j] = 1;
}
}
}
println!("{:?}", result[(n as f64).sqrt() as usize]);
return result;
}
fn main() {
eratosthenes(100_000_000);
}
```

Nim source:

```
import math
proc eratosthenes(n): auto =
result = newSeq[int8](n+1)
result[0] = 1; result[1] = 1
for i in 0 .. int sqrt(float n):
if result[i] == 0:
for j in countup(i*i, n, i):
result[j] = 1
echo(result[int sqrt(float n)])
discard eratosthenes(100_000_000)
```

C source:

```
#include <stdlib.h>
#include <math.h>
char* eratosthenes(int n)
{
char* sieve = calloc(n+1,sizeof(char));
sieve[0] = 1; sieve[1] = 1;
int m = (int) sqrt((double) n);
for(int i = 0; i <= m; i++) {
if(!sieve[i]) {
for (int j = i*i; j <= n; j += i)
sieve[j] = 1;
}
}
printf("%d", sieve[(int) sqrt((double) n)]);
return sieve;
}
int main() {
eratosthenes(100000000);
}
```

Even though this is a microbenchmark, I want to use this as an opportunity to learn more about Rust by learning why it’s not as fast as Nim and C in this scenario, and hopefully to avoid that when I write production code. What am I missing?