-
-
Notifications
You must be signed in to change notification settings - Fork 475
Closed
Description
The best way to define a function from a performance perspective is to use a Function option.
Quoted from documentation(https://expr-lang.org/docs/functions)
This is my benchmark test:
package main
import (
"strconv"
"testing"
"github.com/expr-lang/expr"
)
type EnvStruct struct{}
func (EnvStruct) Atoi(input string) int {
value, _ := strconv.Atoi(input)
return value
}
func BenchmarkCustomFunctions(b *testing.B) {
exprString := `Atoi("42")`
// Method 1: Add to environment
envMap := map[string]interface{}{
"Atoi": func(input string) int {
value, _ := strconv.Atoi(input)
return value
},
}
compiledEnvMap, err := expr.Compile(exprString, expr.Env(envMap))
if err != nil {
b.Fatal(err)
}
// Method 2: Define on struct
envStruct := EnvStruct{}
compiledEnvStruct, err := expr.Compile(exprString, expr.Env(envStruct))
if err != nil {
b.Fatal(err)
}
// Method 3: Using Function option
atoiFunc := expr.Function(
"Atoi",
func(params ...interface{}) (interface{}, error) {
return strconv.Atoi(params[0].(string))
},
strconv.Atoi,
)
compiledFunc, err := expr.Compile(exprString, atoiFunc)
if err != nil {
b.Fatal(err)
}
b.Run("EnvMap", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r, _ := expr.Run(compiledEnvMap, envMap)
if r != 42 {
b.Errorf("got %v, want 42", r)
}
}
})
b.Run("EnvStruct", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r, _ := expr.Run(compiledEnvStruct, envStruct)
if r != 42 {
b.Errorf("got %v, want 42", r)
}
}
})
b.Run("FunctionOption", func(b *testing.B) {
for i := 0; i < b.N; i++ {
r, _ := expr.Run(compiledFunc, nil)
if r != 42 {
b.Errorf("got %v, want 42", r)
}
}
})
}And result
goos: darwin
goarch: arm64
cpu: Apple M1 Pro
BenchmarkCustomFunctions/EnvMap-10 24067287 48.26 ns/op
BenchmarkCustomFunctions/EnvStruct-10 3250443 365.2 ns/op
BenchmarkCustomFunctions/FunctionOption-10 19875295 60.49 ns/op
PASS
ok command-line-arguments 4.534s
goos: darwin
goarch: arm64
cpu: Apple M1 Pro
BenchmarkCustomFunctions/EnvMap-10 23904123 48.59 ns/op
BenchmarkCustomFunctions/EnvStruct-10 3274218 374.6 ns/op
BenchmarkCustomFunctions/FunctionOption-10 19192731 61.28 ns/op
PASS
ok command-line-arguments 4.460s
The performance of map and function methods are very close, there is no particularly obvious difference, and map method is even faster.
Metadata
Metadata
Assignees
Labels
No labels