-
-
Notifications
You must be signed in to change notification settings - Fork 477
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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels