2 unstable releases

0.2.0 Jan 5, 2020
0.1.0 Feb 17, 2019

#1638 in Data structures

MIT/Apache

15KB
118 lines

Soak

License Cargo Documentation

This crate allocates parallel, columnar arrays for a struct's fields.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


lib.rs:

Soak

Soak is a library for transforming data from an Array-of-Structs layout to a Struct-of-Arrays layout.

The natural way to work with a collection of objects in Rust is to represent them as structs, often placed in a [Vec]. This lays out each individual object's fields together in memory:

[field 1, field 2][field 1, field 2][field 1, field 2]...

Often it improves performance to interleave the objects' fields, so that individual fields are grouped together instead:

[field 1, field 1, field 1][field 2, field 2, field 2]...

The primary tools provided by Soak are the Columns trait, which records a struct's layout; and the RawTable type, the eponymous struct of arrays. They can be used together like this:

use core::ptr;
use dioptre::Fields;
use soak::{RawTable, Columns};

#[derive(Fields, Columns)]
struct GameObject {
    position: (f32, f32),
    velocity: (f32, f32),
    health: f32,
}

unsafe fn process(table: &mut RawTable<GameObject>) {
    let positions = table.ptr(GameObject::position);
    let velocities = table.ptr(GameObject::velocity);
    let healths = table.ptr(GameObject::health);

    for i in 0..table.capacity() {
        let position = &mut *positions.add(i);
        let velocity = &mut *velocities.add(i);
        position.0 += velocity.0;
        position.1 += velocity.1;
    }
}

Dependencies

~1.5MB
~35K SLoC