This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/engine/optimize/volatility.md
2025-04-03 09:18:05 +02:00

54 lines
1.9 KiB
Markdown

Volatility Considerations for Full Optimization Level
=====================================================
{{#include ../../links.md}}
Even if a custom function does not mutate state nor cause side-effects, it may still be _volatile_,
i.e. it _depends_ on external environment and does not guarantee the same result for the same inputs.
A perfect example is a function that gets the current time – obviously each run will return a
different value!
```rust
print(get_current_time(true)); // prints the current time
// notice the call to 'get_current_time'
// has constant arguments
// The above, under full optimization level, is rewritten to:
print("10:25AM"); // the function call is replaced by
// its result at the time of optimization!
```
```admonish danger.small "Warning"
**Avoid using [`OptimizationLevel::Full`]** if volatile custom functions are involved.
```
The optimizer, when using [`OptimizationLevel::Full`], _merrily assumes_ that all functions are
_non-volatile_, so when it finds [constant] arguments (or none) it eagerly executes the function
call and replaces it with the result.
This causes the script to behave differently from the intended semantics.
~~~admonish tip "Tip: Mark a function as volatile"
All native functions are assumed to be **non-volatile**, meaning that they are eagerly called under
[`OptimizationLevel::Full`] when all arguments are [constant] (or none).
It is possible to [mark a function defined within a plugin module as volatile]({{rootUrl}}/plugins/module.md#volatile-functions)
to prevent this behavior.
```rust
#[export_module]
mod my_module {
// This function is marked 'volatile' and will not be
// eagerly executed even under OptimizationLevel::Full.
#[rhai_fn(volatile)]
pub get_current_time(am_pm: bool) -> String {
// ...
}
}
```
~~~