Expand description
A Slab is a pre-allocated block of memory, used during the
parse/compile/eval phases to reduce memory allocation/deallocation.
A Slab enables you to perform one single, large allocation at the
beginning of the parse-compile-eval process, rather than many small
allocations. You can also re-use a Slab for multiple expression
parse-compile-eval cycles, greatly reducing the amount of memory
operations. The Slab is the main key to fasteval’s excellent
performance.
You use ExpressionI, ValueI, and InstructionI index types to refer to
elements within the Slab. These special index types are necessary to
side-step the Rust borrow checker, which is not able to understand
borrow-splitting of contiguous allocations (like arrays).
(In other words, these special index types allows fasteval to mutate a
Slab while simultaneously holding references to its contents.)
You usually won’t use any of the Slab method directly. Instead, you’ll
just pass a reference to other functions like parse(),
compile() and eval().
We treat a Slab sort of like a Context in other programming systems.
The Slab contains two fields: ps (“Parse Slab”) and cs
(“Compile Slab”). It is structured like this because of Rust’s borrowing
rules, so that the two fields can be borrowed and mutated independently.
If you use the ez_eval() function, it allocates
a Slab for you. If you are performing the parse/compile/eval process
yourself, then you’ll need to allocate a Slab at the beginning.
§Examples
Here is an example of re-using one Slab for multiple parse/eval cycles:
use fasteval::Evaler; // import this trait so we can call eval().
fn main() -> Result<(), fasteval::Error> {
let parser = fasteval::Parser::new();
let mut slab = fasteval::Slab::new();
let val = parser.parse("1+2*3-4", &mut slab.ps)?.from(&slab.ps).eval(&slab, &mut fasteval::EmptyNamespace)?;
assert_eq!(val, 3.0);
// Let's re-use the same slab again to save memory operations.
// `parse()` will clear the Slab's data. It is important that you
// do not use an old expression after the Slab has been cleared.
let val = parser.parse("5+6*7-8", &mut slab.ps)?.from(&slab.ps).eval(&slab, &mut fasteval::EmptyNamespace)?;
assert_eq!(val, 39.0);
Ok(())
}Structs§
- Compile
Slab CompileSlabis wherecompile()results are stored, located atSlab.cs.- Parse
Slab ParseSlabis whereparse()results are stored, located atSlab.ps.- Slab
- See the
slab moduledocumentation.