As someone who's currently obssessing over the perf of my toy utility, I learnt about the miracle of pre-allocation to reduce run-time allocations, syscalls, etc. Got a 3x reduction in execution time by just creating Vecs with their maximum possible (in my use case) size/capacity, rather than creating empty and letting them expand.
So, having learnt of bump allocation or just pre-allocating in general, I'm trying to understand how I can use elsa (elsa - Rust) in my fn main(), such that the Vecs and arrays created in each of my iterator's iteration (next()) is backed by this FrozenVec or some pre-allocated block of memory.
Not looking to hold the whole input file in memory, as I have an iterator that can read things in serially, then parallellize the crunching.
Each Item returned by the iterator is a Vec of a single type (u8, u16, whatever), and I only need a reference to that Vec, as I won't be modifiying the content, just reading and parsing.
To be honest, this is an advanced topic for me w.r.t understanding all examples.
So any guidance on how to think and go about this will be really helpful.
Thanks for responding.
That's another crate I've been looking at.
cargo add / cargo sync was behaving weird earlier today, so couldn't get this added to my project.
So... I'd create a new bump, then put that in my iter's definition struct, then use it within fn next() for future with_capacity_in requests?
It should be possible to combine arena allocators with the “thread_local” crate (e.g. using the type ThreadLocal<Bump>), which will result in one separate arena per thread, but that’s just some extra chunking
The bumpalo-herd crate provides a pool of Bump allocators for use in such situations.
There's nothing in rayon that would be affected, nor anything particularly weird there, just that it's an example of a threaded environment where you have to care about Send and Sync.
@cuviper I did see bumpalo-herd, but to be honest, although I understand all this conceptually, I'm currently struggling to figure out how to implement this in a case like this Rust Playground
... which I call in main like so:
let file_struct = RecordIter { line };
let output: Vec<_> = file_struct
.par_bridge()
.map(parse)
.filter(|x| x.contains("some.string"))
.collect();