reorganize module
This commit is contained in:
85
_archive/rhai_engine/rhaibook/engine/optimize/op-eval.md
Normal file
85
_archive/rhai_engine/rhaibook/engine/optimize/op-eval.md
Normal file
@@ -0,0 +1,85 @@
|
||||
Eager Operator Evaluation
|
||||
=========================
|
||||
|
||||
{{#include ../../links.md}}
|
||||
|
||||
Most operators are actually function calls, and those functions can be overridden, so whether they
|
||||
are optimized away depends on the situation:
|
||||
|
||||
```admonish info.side.wide "No external functions"
|
||||
|
||||
Rhai guarantees that no external function will be run, which may trigger side-effects
|
||||
(unless the optimization level is [`OptimizationLevel::Full`]).
|
||||
```
|
||||
|
||||
* if the operands are not [constant] values, it is **not** optimized;
|
||||
|
||||
* if the [operator] is [overloaded][operator overloading], it is **not** optimized because the
|
||||
overloading function may not be _pure_ (i.e. may cause side-effects when called);
|
||||
|
||||
* if the [operator] is not _built-in_ (see list of [built-in operators]), it is **not** optimized;
|
||||
|
||||
* if the [operator] is a [built-in operator] for a [standard type][standard types], it is called and
|
||||
replaced by a [constant] result.
|
||||
|
||||
```js
|
||||
// The following is most likely generated by machine.
|
||||
|
||||
const DECISION = 1; // this is an integer, one of the standard types
|
||||
|
||||
if DECISION == 1 { // this is optimized into 'true'
|
||||
:
|
||||
} else if DECISION == 2 { // this is optimized into 'false'
|
||||
:
|
||||
} else if DECISION == 3 { // this is optimized into 'false'
|
||||
:
|
||||
} else {
|
||||
:
|
||||
}
|
||||
|
||||
// Or an equivalent using 'switch':
|
||||
|
||||
switch DECISION {
|
||||
1 => ..., // this statement is promoted
|
||||
2 => ..., // this statement is eliminated
|
||||
3 => ..., // this statement is eliminated
|
||||
_ => ... // this statement is eliminated
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Pre-Evaluation of Constant Expressions
|
||||
--------------------------------------
|
||||
|
||||
Because of the eager evaluation of [operators][built-in operators] for [standard types], many
|
||||
[constant] expressions will be evaluated and replaced by the result.
|
||||
|
||||
```rust
|
||||
let x = (1+2) * 3 - 4/5 % 6; // will be replaced by 'let x = 9'
|
||||
|
||||
let y = (1 > 2) || (3 <= 4); // will be replaced by 'let y = true'
|
||||
```
|
||||
|
||||
For operators that are not optimized away due to one of the above reasons, the function calls are
|
||||
simply left behind.
|
||||
|
||||
```rust
|
||||
// Assume 'new_state' returns some custom type that is NOT one of the standard types.
|
||||
// Also assume that the '==' operator is defined for that custom type.
|
||||
const DECISION_1 = new_state(1);
|
||||
const DECISION_2 = new_state(2);
|
||||
const DECISION_3 = new_state(3);
|
||||
|
||||
if DECISION == 1 { // NOT optimized away because the operator is not built-in
|
||||
: // and may cause side-effects if called!
|
||||
:
|
||||
} else if DECISION == 2 { // same here, NOT optimized away
|
||||
:
|
||||
} else if DECISION == 3 { // same here, NOT optimized away
|
||||
:
|
||||
} else {
|
||||
:
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, turn the optimizer to [`OptimizationLevel::Full`].
|
Reference in New Issue
Block a user