Files
expr/docs/Optimizations.md
T

1.9 KiB

Optimizations

Expr has a bunch of optimization which will produce more optimal program during compile step.

In array

value in ['foo', 'bar', 'baz']

If expr finds an in or not in expression with an array, it will be transformed into:

value in {"foo": true, "bar": true, "baz": true}

Constant folding

Arithmetic expressions with constants is computed on compile step and replaced with result.

-(2-5)**3-2/(+4-3)+-2

Will be compiled to just single number:

23

So in expressions it's safe to use some arithmetics for better readability:

percentage > 0.3 * 100

As it will be simpified to:

percentage > 30

In range

user.Age in 18..32

Will be replaced with binary operator:

18 <= user.Age && user.Age <= 32

not in operator will also work.

Const range

1..10_000

Ranges computed on compile stage, repleced with preallocated slices.

Const expr

If some function marked as constant expression with expr.ConstExpr. It will be replaced with result of call, if all arguments are constants.

expr.ConstExpt("fib")
fib(42)

Will be replaced with result of fib(42) on compile step. No need to calculate it during runtime.

ConstExpr Example

Reuse VM

It is possible to reuse a virtual machine between re-runs on the program. This adds a small increase in performance (from 4% to 40% depending on a program).

package main

import (
	"fmt"
	"github.com/antonmedv/expr"
	"github.com/antonmedv/expr/vm"
)

func main() {
	env := map[string]interface{}{
		"foo": 1,
		"bar": 2,
	}

	program, err := expr.Compile("foo + bar", expr.Env(env))
	if err != nil {
		panic(err)
	}

	// Reuse this vm instance between runs
	v := vm.VM{}

	out, err := v.Run(program, env)
	if err != nil {
		panic(err)
	}

	fmt.Print(out)
}