Add slice swap benchmark.

Adds a benchmark of various different ways of swapping the elements of
two slices, including several implementations in C.

Change-Id: I7ff490aefee6edfe5d7630b851278ce1fc385e8c
diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs
new file mode 100644
index 0000000..3f69369
--- /dev/null
+++ b/benches/benchmarks.rs
@@ -0,0 +1,222 @@
+#![cfg(test)]
+#![feature(test)]
+#![feature(slice_fill)]
+
+extern crate num;
+extern crate test;
+
+use rust_samples::{cswap, swap};
+
+use heapless::consts::{U10, U100, U1000, U10000, U100000, U1000000};
+use num::{one, zero, Num};
+use test::{black_box, Bencher};
+
+fn bench_swap_loop<T, N>(b: &mut Bencher)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Copy,
+{
+    let (mut arr1, mut arr2) = bench_swap_setup::<T, N>();
+
+    b.iter(|| {
+        swap::swap_loop(&mut arr1, &mut arr2);
+        black_box(&arr1);
+        black_box(&arr2);
+    });
+}
+
+fn bench_swap_ptrswap<T, N>(b: &mut Bencher)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Copy,
+{
+    let (mut arr1, mut arr2) = bench_swap_setup::<T, N>();
+
+    b.iter(|| {
+        swap::swap_ptrswap(&mut arr1, &mut arr2);
+        black_box(&arr1);
+        black_box(&arr2);
+    });
+}
+
+fn bench_cswap_loop<T, N>(b: &mut Bencher)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Copy,
+{
+    let (mut arr1, mut arr2) = bench_swap_setup::<T, N>();
+
+    b.iter(|| {
+        cswap::cswap_loop(&mut arr1, &mut arr2);
+        black_box(&arr1);
+        black_box(&arr2);
+    });
+}
+
+fn bench_cswap_alloca<T, N>(b: &mut Bencher)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Copy,
+{
+    let (mut arr1, mut arr2) = bench_swap_setup::<T, N>();
+
+    b.iter(|| {
+        cswap::cswap_alloca(&mut arr1, &mut arr2);
+        black_box(&arr1);
+        black_box(&arr2);
+    });
+}
+
+/// Allocates two vectors of fixed length on the heap.
+fn bench_swap_setup<T, N>() -> (Vec<T>, Vec<T>)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Clone,
+{
+    let mut arr1: Vec<T> = Vec::new();
+    let mut arr2 = arr1.clone();
+
+    arr1.resize(N::to_usize(), black_box(zero()));
+    arr2.resize(N::to_usize(), black_box(one()));
+
+    (arr1, arr2)
+}
+
+/// A heapless version of `bench_swap_setup`.
+fn _bench_swap_setup_heapless<T, N>() -> (heapless::Vec<T, N>, heapless::Vec<T, N>)
+where
+    N: heapless::ArrayLength<T>,
+    T: Num + Clone,
+{
+    let mut arr1: heapless::Vec<T, N> = heapless::Vec::new();
+    let mut arr2 = arr1.clone();
+
+    arr1.resize(N::to_usize(), black_box(zero()))
+        .expect("insufficient stack space");
+    arr2.resize(N::to_usize(), black_box(one()))
+        .expect("insufficient stack space");
+
+    (arr1, arr2)
+}
+
+type BenchInt = u8;
+
+#[bench]
+fn bench_swap_loop_len_10(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U10>(b);
+}
+
+#[bench]
+fn bench_swap_loop_len_100(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U100>(b);
+}
+
+#[bench]
+fn bench_swap_loop_len_1000(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U1000>(b);
+}
+
+#[bench]
+fn bench_swap_loop_len_10000(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U10000>(b);
+}
+
+#[bench]
+fn bench_swap_loop_len_100000(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U100000>(b);
+}
+
+#[bench]
+fn bench_swap_loop_len_1000000(b: &mut Bencher) {
+    bench_swap_loop::<BenchInt, U1000000>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_10(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U10>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_100(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U100>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_1000(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U1000>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_10000(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U10000>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_100000(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U100000>(b);
+}
+
+#[bench]
+fn bench_swap_ptrswap_len_1000000(b: &mut Bencher) {
+    bench_swap_ptrswap::<BenchInt, U1000000>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_10(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U10>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_100(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U100>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_1000(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U1000>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_10000(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U10000>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_100000(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U100000>(b);
+}
+
+#[bench]
+fn bench_cswap_loop_len_1000000(b: &mut Bencher) {
+    bench_cswap_loop::<BenchInt, U1000000>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_10(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U10>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_100(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U100>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_1000(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U1000>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_10000(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U10000>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_100000(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U100000>(b);
+}
+
+#[bench]
+fn bench_cswap_alloca_len_1000000(b: &mut Bencher) {
+    bench_cswap_alloca::<BenchInt, U1000000>(b);
+}