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 CompileSlab
is wherecompile()
results are stored, located atSlab.cs
.- Parse
Slab ParseSlab
is whereparse()
results are stored, located atSlab.ps
.- Slab
- See the
slab module
documentation.