File: Optimizations.md

package info (click to toggle)
golang-github-antonmedv-expr 1.8.9-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 4,524 kB
  • sloc: makefile: 6
file content (119 lines) | stat: -rw-r--r-- 1,959 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Optimizations

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

## In array

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

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

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

## Constant folding

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

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

Will be compiled to just single number:

```js
23
```

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

```js
percentage > 0.3 * 100
```

As it will be simpified to:

```js
percentage > 30
```

## In range

```js
user.Age in 18..32
```

Will be replaced with binary operator:

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

`not in` operator will also work.

## Const range

```js
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.

```go
expr.ConstExpt("fib")
```

```js
fib(42)
``` 

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

[ConstExpr Example](https://pkg.go.dev/github.com/antonmedv/expr?tab=doc#ConstExpr)

## 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).

```go
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)
}
```

* [Contents](README.md)