#![allow(clippy::needless_return)] use soa_derive::StructOfArray; use bencher::{Bencher, benchmark_group, benchmark_main}; #[derive(StructOfArray)] pub struct Small { x: f64, y: f64, z: f64, } impl Small { fn new() -> Small { Small { x: 1.0, y: 0.2, z: -2.3, } } fn aos_vec(size: usize) -> Vec { let mut vec = Vec::new(); for _ in 0..size { vec.push(Small::new()) } return vec; } fn soa_vec(size: usize) -> SmallVec { let mut vec = SmallVec::new(); for _ in 0..size { vec.push(Small::new()) } return vec; } } #[derive(StructOfArray)] pub struct Big { position: (f64, f64, f64), velocity: (f64, f64, f64), data: [usize; 18], name: String, userdata: String } impl Big { fn new() -> Big { Big { position: (1.0, 0.2, -2.3), velocity: (1.0, 0.2, -2.3), data: [67; 18], name: "foo".into(), userdata: "bar".into() } } fn aos_vec(size: usize) -> Vec { let mut vec = Vec::new(); for _ in 0..size { vec.push(Big::new()) } return vec; } fn soa_vec(size: usize) -> BigVec { let mut vec = BigVec::new(); for _ in 0..size { vec.push(Big::new()) } return vec; } } fn aos_small_push(bencher: &mut Bencher) { let mut vec = Vec::new(); bencher.iter(||{ vec.push(Small::new()) }) } fn soa_small_push(bencher: &mut Bencher) { let mut vec = SmallVec::new(); bencher.iter(||{ vec.push(Small::new()) }) } fn aos_big_push(bencher: &mut Bencher) { let mut vec = Vec::new(); bencher.iter(||{ vec.push(Big::new()) }) } fn soa_big_push(bencher: &mut Bencher) { let mut vec = BigVec::new(); bencher.iter(||{ vec.push(Big::new()) }) } fn aos_small_do_work_100k(bencher: &mut Bencher) { let vec = Small::aos_vec(100_000); bencher.iter(||{ let mut s = 0.0; for v in &vec { s += v.x + v.y; } s }) } fn soa_small_do_work_100k(bencher: &mut Bencher) { let vec = Small::soa_vec(100_000); bencher.iter(||{ let mut s = 0.0; for (x, y) in vec.x.iter().zip(&vec.y) { s += x + y; } s }) } fn aos_big_do_work_10k(bencher: &mut Bencher) { let vec = Big::aos_vec(10_000); bencher.iter(||{ let mut s = 0.0; for v in &vec { s += v.position.0 + v.velocity.0 * 0.1; } s }) } fn aos_big_do_work_100k(bencher: &mut Bencher) { let vec = Big::aos_vec(100_000); bencher.iter(||{ let mut s = 0.0; for v in &vec { s += v.position.0 + v.velocity.0 * 0.1; } s }) } fn soa_big_do_work_10k(bencher: &mut Bencher) { let vec = Big::soa_vec(10_000); bencher.iter(||{ let mut s = 0.0; for (position, velocity) in vec.position.iter().zip(&vec.velocity) { s += position.0 + velocity.0; } s }) } fn soa_big_do_work_100k(bencher: &mut Bencher) { let vec = Big::soa_vec(100_000); bencher.iter(||{ let mut s = 0.0; for (position, velocity) in vec.position.iter().zip(&vec.velocity) { s += position.0 + velocity.0; } s }) } benchmark_group!(aos, aos_small_push, aos_big_push, aos_small_do_work_100k, aos_big_do_work_10k, aos_big_do_work_100k ); benchmark_group!(soa, soa_small_push, soa_big_push, soa_small_do_work_100k, soa_big_do_work_10k, soa_big_do_work_100k ); benchmark_main!(soa, aos);