From cfd63fbc4f33daa6ac81b0cbd2be0cd285ea176a Mon Sep 17 00:00:00 2001 From: Armin Becher Date: Wed, 1 Apr 2020 23:29:06 +0200 Subject: [PATCH] Mutability and more benchmarks --- README.md | 5 +-- benches/benches.rs | 45 ++++++++++++++++++++++++-- src/lib.rs | 79 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 120 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fd3813e..a617cd9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# nvector -Benchmark n dimensional vectors in rust +# Grid + +Data structure grid for rust. Provide a two dimensional data storage that is easy to use and fast. diff --git a/benches/benches.rs b/benches/benches.rs index fb9bd74..1d12f2a 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -20,7 +20,7 @@ fn get_vec_vec(x: usize, y: usize) -> u32 { fn get_vec_flat(x: usize, y: usize) -> u32 { let mat = init_vec_flat(10); - mat[x / 10 + y % 10] + mat[x * 10 + y % 10] } fn get_grid(x: usize, y: usize) -> u32 { @@ -28,11 +28,36 @@ fn get_grid(x: usize, y: usize) -> u32 { mat[x][y] } +fn get_grid_fn(x: usize, y: usize) { + let mat = init_grid(10); + mat.get(x, y); +} + +fn set_vec_vec(x: usize, y: usize) { + let mut mat = init_vec_vec(10); + mat[x][y] = 10; +} +fn set_vec_flat(x: usize, y: usize) { + let mut mat = init_vec_flat(10); + mat[x * 10 + y % 10] = 10; +} + +fn set_grid(x: usize, y: usize) { + let mut mat = init_grid(10); + mat[x][y] = 10; +} + fn criterion_benchmark(c: &mut Criterion) { - c.bench_function("Init vec vec 10x10", |b| b.iter(|| init_vec_vec(black_box(10)))); - c.bench_function("Init vec flat 10x10", |b| b.iter(|| init_vec_flat(black_box(10)))); + // Init + c.bench_function("Init vec vec 10x10", |b| { + b.iter(|| init_vec_vec(black_box(10))) + }); + c.bench_function("Init vec flat 10x10", |b| { + b.iter(|| init_vec_flat(black_box(10))) + }); c.bench_function("Init grid 10x10", |b| b.iter(|| init_grid(black_box(10)))); + // Get c.bench_function("Get vec vec 10x10", |b| { b.iter(|| get_vec_vec(black_box(2), black_box(3))) }); @@ -42,6 +67,20 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Get grid 10x10", |b| { b.iter(|| get_grid(black_box(2), black_box(3))) }); + c.bench_function("Get grid fn 10x10", |b| { + b.iter(|| get_grid_fn(black_box(2), black_box(3))) + }); + + //Set + c.bench_function("Set vec vec 10x10", |b| { + b.iter(|| set_vec_vec(black_box(2), black_box(3))) + }); + c.bench_function("Set vec flat 10x10", |b| { + b.iter(|| set_vec_flat(black_box(2), black_box(3))) + }); + c.bench_function("Set grid 10x10", |b| { + b.iter(|| set_grid(black_box(2), black_box(3))) + }); } criterion_group!(benches, criterion_benchmark); diff --git a/src/lib.rs b/src/lib.rs index 8916263..7cf2f4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,20 +1,30 @@ use std::ops::Index; +use std::ops::IndexMut; pub struct Grid { data: Vec, - row_len: usize, + columns: usize, + rows: usize, } impl Grid { pub fn new(rows: usize, columns: usize, data: T) -> Grid { + if rows < 1 || columns < 1 { + panic!("Grid size of rows and columns must be greater than zero."); + } Grid { data: vec![data; rows * columns], - row_len: rows, + columns: columns, + rows: rows, } } pub fn get(&self, row: usize, column: usize) -> Option<&T> { - self.data.get(row / self.row_len + column % self.row_len) + self.data.get(row * self.columns + column % self.columns) + } + + pub fn size(&self) -> (usize, usize) { + (self.rows, self.columns) } } @@ -22,7 +32,25 @@ impl Index for Grid { type Output = [T]; fn index(&self, idx: usize) -> &Self::Output { - &self.data[(idx / &self.row_len)..] + if idx >= self.rows { + panic!( + "index out of bounds: grid has {:?} but the index is {:?}", + self.rows, idx + ); + } + &self.data[(idx * &self.columns)..] + } +} + +impl IndexMut for Grid { + fn index_mut(&mut self, idx: usize) -> &mut Self::Output { + if idx >= self.rows { + panic!( + "index out of bounds: grid has {:?} but the index is {:?}", + self.rows, idx + ); + } + &mut self.data[(idx * &self.columns)..] } } @@ -36,16 +64,59 @@ mod test { Grid::new(1, 2, 1.2); Grid::new(1, 2, 'a'); } + #[test] + #[should_panic] + fn ctr_panics() { + Grid::new(0, 2, 3); + } + + #[test] + #[should_panic] + fn ctr_panics_2() { + Grid::new(1, 0, 3); + } #[test] fn get() { let grid = Grid::new(1, 2, 3); assert_eq!(grid.get(0, 0), Some(&3)); } + #[test] + fn get_none() { + let grid = Grid::new(1, 2, 3); + assert_eq!(grid.get(1, 0), None); + } #[test] fn idx() { let grid = Grid::new(1, 2, 3); assert_eq!(grid[0][0], 3); } + + #[test] + #[should_panic] + fn idx_panic_1() { + let grid = Grid::new(1, 2, 3); + grid[20][0]; + } + + #[test] + #[should_panic] + fn idx_panic_2() { + let grid = Grid::new(1, 2, 3); + grid[0][20]; + } + + #[test] + fn idx_set() { + let mut grid = Grid::new(1, 2, 3); + grid[0][0] = 4; + assert_eq!(grid[0][0], 4); + } + + #[test] + fn size() { + let grid = Grid::new(1, 2, 3); + assert_eq!(grid.size(), (1, 2)); + } }