https://github.com/xaionaro-go/rpn
Reverse Polish Notation for Go (golang)
https://github.com/xaionaro-go/rpn
benchmark cc0 fast go golang jit performance reverse-polish-notation rpn
Last synced: 20 days ago
JSON representation
Reverse Polish Notation for Go (golang)
- Host: GitHub
- URL: https://github.com/xaionaro-go/rpn
- Owner: xaionaro-go
- License: cc0-1.0
- Created: 2020-10-26T19:16:56.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2025-08-18T13:06:53.000Z (11 months ago)
- Last Synced: 2025-08-18T14:18:51.752Z (11 months ago)
- Topics: benchmark, cc0, fast, go, golang, jit, performance, reverse-polish-notation, rpn
- Language: Go
- Homepage:
- Size: 65.4 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://pkg.go.dev/github.com/xaionaro-go/rpn?tab=doc)
[](https://goreportcard.com/report/github.com/xaionaro-go/rpn)
[](https://travis-ci.org/xaionaro-go/rpn)
[](https://coveralls.io/github/xaionaro-go/rpn?branch=master)
To the extent possible under law,
Dmitrii Okunev
has waived all copyright and related or neighboring rights to
Reverse Polish Notation for Go.
This work is published from:
Ireland.
# About
`github.com/xaionaro-go/rpn` is an implementation of [Reverse Polish Notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation).
The implementation is focused on fast evaluation (but slow parsing).
# Quick start
```go
package main
import (
"fmt"
"github.com/xaionaro-go/rpn"
"github.com/xaionaro-go/rpn/types"
)
type variables struct {
X float64
}
func (r *variables) Resolve(sym string) (types.ValueLoader, error) {
switch sym {
case "x":
return types.FuncValue(func(any) float64 {
return r.X
}), nil
}
return nil, fmt.Errorf("symbol '%s' not found", sym)
}
func main() {
vars := &variables{}
expr, err := rpn.Parse("x 2 *", vars)
if err != nil {
panic(err)
}
vars.X = 1
_, _ = fmt.Println(expr.Eval(nil))
vars.X = 3
_, _ = fmt.Println(expr.Eval(nil))
}
```
The output is:
```
2
6
```
# Benchmark
There are 5 approaches implemented (`callslice`, `calltree`, `exprtree`, `compile` and `tokenslice`):
```
goos: linux
goarch: amd64
pkg: github.com/xaionaro-go/rpn/tests
cpu: AMD Ryzen 9 5900X 12-Core Processor
BenchmarkExpr_Eval/cache_true/3_constant_values/callslice-24 338823202 3.526 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_constant_values/calltree-24 342666187 3.501 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_constant_values/exprtree-24 337961120 3.626 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_constant_values/compile-24 342394530 3.487 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_constant_values/tokenslice-24 334232605 3.556 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_constant_values/default-24 344161088 3.481 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/exprtree-24 328156056 3.539 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/compile-24 339983692 3.574 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/tokenslice-24 339623660 3.486 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/default-24 346571980 3.560 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/callslice-24 342680188 3.477 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/3_variables/calltree-24 320866833 3.574 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/tokenslice-24 341432474 3.493 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/default-24 329531038 3.569 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/callslice-24 341855184 3.537 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/calltree-24 343456281 3.494 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/exprtree-24 334949788 3.648 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10_variables/compile-24 343865816 3.488 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/calltree-24 339102571 3.527 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/exprtree-24 337756276 3.527 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/compile-24 333295226 3.548 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/tokenslice-24 346515900 3.511 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/default-24 341047189 3.482 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/100_variables/callslice-24 340326940 3.564 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/callslice-24 341819227 3.489 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/calltree-24 345551792 3.552 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/exprtree-24 344173688 3.509 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/compile-24 339122401 3.569 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/tokenslice-24 340029790 3.527 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/1000_variables/default-24 338550138 3.509 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/exprtree-24 340234605 3.544 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/compile-24 344656420 3.476 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/tokenslice-24 334536746 3.602 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/default-24 338500122 3.505 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/callslice-24 337411789 3.648 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_true/10000_variables/calltree-24 341668298 3.593 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/callslice-24 141478860 8.563 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/calltree-24 259093815 4.681 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/exprtree-24 82469947 14.70 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/compile-24 100000000 11.25 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/tokenslice-24 71216802 17.23 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_constant_values/default-24 245641957 4.803 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/callslice-24 82744274 14.53 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/calltree-24 100000000 10.85 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/exprtree-24 52943655 21.73 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/compile-24 59577981 20.51 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/tokenslice-24 54594726 22.58 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/3_variables/default-24 100000000 10.83 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/compile-24 22511331 54.22 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/tokenslice-24 17895859 67.43 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/default-24 33715436 34.74 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/callslice-24 25407411 46.86 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/calltree-24 31303549 36.59 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10_variables/exprtree-24 17891308 68.98 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/default-24 2765348 448.3 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/callslice-24 2627880 459.6 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/calltree-24 2836452 429.9 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/exprtree-24 1637896 724.5 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/compile-24 1581406 754.3 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/100_variables/tokenslice-24 1773808 671.8 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/compile-24 156962 7794 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/tokenslice-24 185878 6509 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/default-24 246588 4806 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/callslice-24 244425 4858 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/calltree-24 276615 4335 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/1000_variables/exprtree-24 170758 6955 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/callslice-24 22401 52229 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/calltree-24 26130 46719 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/exprtree-24 15268 78926 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/compile-24 15032 81232 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/tokenslice-24 18117 66644 ns/op 0 B/op 0 allocs/op
BenchmarkExpr_Eval/cache_false/10000_variables/default-24 25033 46930 ns/op 0 B/op 0 allocs/op
```
The default approach for small expressions is `calltree`, and
for larger expression is `callslice`, so if you will import
`github.com/xaionaro-go/rpn` then if you will use them.