Last active
June 11, 2024 09:08
-
-
Save rhnvrm/db4567fcd87b2cb8e997999e1366d406 to your computer and use it in GitHub Desktop.
Benchmark Results of govaluate vs cel-go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"testing" | |
"github.com/Knetic/govaluate" | |
"github.com/google/cel-go/cel" | |
"github.com/google/cel-go/checker/decls" | |
"github.com/google/cel-go/common/types" | |
"github.com/google/cel-go/common/types/ref" | |
"github.com/google/cel-go/interpreter/functions" | |
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1" | |
) | |
func BenchmarkCelGo(b *testing.B) { | |
expr := "((TestDouble >= 1.0 || TestString.TestFunction() == 'HelloWorld') && (TestDouble + 1.0 >= 0.0)) || Now > TestTime" | |
decls := cel.Declarations( | |
// Identifiers used within this expression. | |
decls.NewIdent("TestDouble", decls.Double, nil), | |
decls.NewIdent("TestString", decls.String, nil), | |
decls.NewIdent("TestTime", decls.Uint, nil), | |
decls.NewIdent("Now", decls.Uint, nil), | |
decls.NewFunction("TestFunction", decls.NewInstanceOverload("TestFunction", | |
[]*exprpb.Type{decls.String}, | |
decls.String)), | |
) | |
e, err := cel.NewEnv(decls) | |
if err != nil { | |
b.Fatalf("environment creation error: %s\n", err) | |
} | |
// Parse and check the expression. | |
p, iss := e.Parse(expr) | |
if iss != nil && iss.Err() != nil { | |
b.Fatal(iss.Err()) | |
} | |
c, iss := e.Check(p) | |
if iss != nil && iss.Err() != nil { | |
b.Fatal(iss.Err()) | |
} | |
// Create the program. | |
funcs := cel.Functions( | |
&functions.Overload{ | |
Operator: "TestFunction", | |
Unary: func(value ref.Val) ref.Val { | |
ts, ok := value.(types.String) | |
if !ok { | |
return types.NewErr( | |
"invalid key of type '%v' and value '%v' to obj.get(key, def)", | |
value.Type(), ts) | |
} | |
return types.String("Hello" + ts) | |
}, | |
}) | |
prg, err := e.Program(c, funcs) | |
if err != nil { | |
b.Fatalf("program creation error: %s\n", err) | |
} | |
parameters := map[string]interface{}{ | |
"TestDouble": 0.0, | |
"TestString": "World", | |
"TestTime": 0, | |
"Now": 1, | |
} | |
for n := 0; n < b.N; n++ { | |
prg.Eval(parameters) | |
} | |
} | |
func BenchmarkGovaluate(b *testing.B) { | |
expr := "((TestDouble >= 1.0 || TestFunction(TestString) == 'HelloWorld') && (TestDouble + 1.0 >= 0.0)) || Now > TestTime" | |
functions := map[string]govaluate.ExpressionFunction{ | |
"TestFunction": func(args ...interface{}) (interface{}, error) { | |
ts, ok := args[0].(string) | |
if !ok { | |
return nil, fmt.Errorf("error: %v", ts) | |
} | |
return "Hello" + ts, nil | |
}, | |
} | |
expression, _ := govaluate.NewEvaluableExpressionWithFunctions(expr, functions) | |
parameters := map[string]interface{}{ | |
"TestDouble": 0.0, | |
"TestString": "World", | |
"TestTime": 0, | |
"Now": 1, | |
} | |
for n := 0; n < b.N; n++ { | |
expression.Evaluate(parameters) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
go test -cpuprofile cpu.prof -memprofile mem.prof -benchmem -bench . | |
goos: linux | |
goarch: amd64 | |
pkg: benchcelgo | |
BenchmarkCelGo-4 2000000 656 ns/op 88 B/op 5 allocs/op | |
BenchmarkGovaluate-4 2000000 702 ns/op 72 B/op 5 allocs/op | |
PASS | |
ok benchcelgo 4.321s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another benchmark for different lang including cel-go and https://expr-lang.org: