ary
Full source code
C++
// -*- mode: c++ -*-
// $Id$
// http://www.bagley.org/~doug/shootout/
#include <cstdlib>
#include <iostream>
#include <vector>
int
main(int argc, char *argv[]) {
#ifdef SMALL_PROBLEM_SIZE
#define LENGTH 900000
#else
#define LENGTH 9000000
#endif
int i, n = ((argc == 2) ? atoi(argv[1]) : LENGTH);
typedef std::vector<int> ARY;
ARY x(n);
ARY y(n);
for (i=0; i<n; i++) {
x[i] = i;
}
for (int i = n - 1; i >= 0; --i) {
y[i] = x[i];
}
std::cout << y.back() << std::endl;
}
Rust
// Adapted from https://github.com/llvm/llvm-test-suite and // http://www.bagley.org/~doug/shootout/ use std::env; #[cfg(feature = "small_problem_size")] const LENGTH: i32 = 900000; #[cfg(not(feature = "small_problem_size"))] const LENGTH: i32 = 9000000; fn main() { let mut args = env::args(); let n = if args.len() == 2 { args.nth(1).unwrap().parse::<i32>().unwrap() } else { LENGTH }; let mut x = Vec::<i32>::new(); x.resize(n as usize, 0); let mut y = Vec::<i32>::new(); y.resize(n as usize, 0); for i in 0..n { x[i as usize] = i; } for i in (0..n).rev() { y[i as usize] = x[i as usize]; } println!("{}", y[(n - 1) as usize]); }
Porting notes
Initializing vectors of type i32
and of size n
as local, mutable variables
C++
typedef std::vector<int> ARY;
ARY x(n);
ARY y(n);
Rust
#![allow(unused)] fn main() { let mut x = Vec::<i32>::new(); x.resize(n as usize, 0); let mut y = Vec::<i32>::new(); y.resize(n as usize, 0); }
We initialize the two vectors, x
and y
using let mut
. let
is the standard way to declare a local variable and mut
is added because we will modify (mutate) the vector later.
When initializing a Vec
of element type i32
, we put the element type i32
in angly brackets as in Vec::<i32>
, as opposed to the C++ style Vec<i32>
.
As there isn't currently a way to initialize a Vec
with a given size n
in one shot in Rust, we initialize a vVec
of size zero and then resize to n
with default element value 0
.
The vector indices in Rust are of type usize
like size_t
and there are no implicit integer conversions, we need to cast n
(of type i32
) to usize
using the as
keyword as in n as usize
.
Writing for
range loops
C++
for (i=0; i<n; i++) {
x[i] = i;
}
for (int i = n - 1; i >= 0; --i) {
y[i] = x[i];
}
Rust
#![allow(unused)] fn main() { for i in 0..n { x[i as usize] = i; } for i in (0..n).rev() { y[i as usize] = x[i as usize]; } }
A for
range loop is written as for i in 0..n { ... }
. The loop iterates with the index range 0
up to n - 1
induction variable where n
is exclusive. There are no parentheses around the for loop header like the if statement condition expression. It's equivalent to for (int i = 0; i < n; ++i) { ... }
in C++.
There is no general for
loop in Rust where the loop variable declaration, the loop termination condition and the loop increment statements are spelled out and can be customizable. We would use while
loops instead.
To make n
to be inclusive, we would write for i in 0..<=n { ... }
.
A for
range loop in the reverse order is written as for i in (0..n).rev() { ... }
. This is equivalent to for (int i = n - 1; i >= 0; --i) { ... }
in C++.
Since the variable i
is of type i32
, we convert it to usize
, as in i as usize
.