The purpose of Rhai is not to be blazing fast, but to make it as easy and versatile as possible to integrate with native Rust applications.
What you lose from running an AST walker, you gain back from increased flexibility.
The following benchmarks were run on a 2.6GHz Linux VM comparing performance-optimized and full builds of Rhai with Python 3 and V8 (Node.js).
|Fibonacci||2.25s||3.2s||0.6s||0.07s||stresses recursive function calls|
|1M loop||0.13s||0.2s||0.08s||0.05s||a simple counting loop (1 million iterations) that must run as fast as possible|
|Prime numbers||0.85s||1.2s||0.4s||0.09s||a closer-to-real-life calculation workload|
In general, Rhai is roughly 2x slower than Python 3, which is a bytecodes interpreter, for typical real-life workloads.
Small data structures
Essential AST and runtime data structures are packed small and kept together to maximize cache friendliness.
Functions are dispatched based on pre-calculated hashes.
Variables are mostly accessed through pre-calculated offsets to the variables file (a
It is seldom necessary to look something up by name.
Function resolutions are cached so they do not incur lookup costs after a couple of calls.
Maintaining a scope chain is deliberately avoided by design so function scopes do not pay any speed penalty. This allows variables data to be kept together in a contiguous block, avoiding allocations and fragmentation while being cache-friendly.
Rhai uses immutable strings to bypass cloning issues.
In a typical script evaluation run, no data is shared and nothing is locked (other than variables captured by closures).
Rhai deliberately keeps the language small and lean by omitting advanced language features such as classes, inheritance, interfaces, generics, first-class functions/closures, pattern matching, monads (whatever), concurrency, async etc.
Focus is on flexibility and ease of use instead of a powerful, expressive language.
In actual practice, it is usually best to expose a Rust API into Rhai for scripts to call.
All the core functionalities should be written in Rust, with Rhai being the dynamic control layer.
This is similar to some dynamic languages where most of the core functionalities reside in a C/C++ standard library (e.g. Python 3).