Replies: 12 comments 1 reply
You can find the complete test cases here: https://github.com/p1g3/golang-expression-evaluation-comparison |
|
I see. Switch to this type for expr as well: func(args ...interface{}) interface{} For celgo and govaluate you are using predefined type. In expr it called fast call. |
|
I modified the code to: However, the benchmark results show that this has not been very helpful. |
Is it true that while expr is much more concise and clear than go-cel and govaluate, the cost of doing so is sacrificing some performance? |
So you think modifying the funccall benchmark to what would make it run faster? |
The culprit with fastfunc although faster is fetchfn.. I just fetch the func directly from fetcher. fetchFN uses reflection and that is a killer. call := vm.constant().(Call)
funcs := fetcher.Fetch(call.Name)In my case I ensure all the fast funcs are not defined as methods. Anton .. would love to see you re-instill fetcher as an option for those that can use it. |
|
@gitperson1980 those bench are made at @master? |
|
I did the benchmarks many moons back. I did it against v1.9.0. I still use v1.9.0 as it provides fetcher and fetcher is infinitely hackable to gain performance in my use cases. I love the fetcher functionality! |
|
Also above 3 switch/case statements in fetcher.. Go compiler switches to binary search from a linear search. |
Only for big switches. |
|
What is the definition of big? Some of my fetchers have 50 case statements. It goes from O(n) to O(log n) with binary search. |
|
I did some investigation. I added updated benchmarks in antonmedv/golang-expression-evaluation-comparison@6a03e5c It is true, cel-go func calls now are faster. The reason for this is that Expr fetches function from the environment on the eval step, and cel-go does it on compile step. So Expr does an additional step, but this can be improved and Expr can also do such optimization on compile step. Another huge difference is how functions are configured. It's super easy to declare a function in Expr: params := map[string]interface{}{
"join": func(a, b string) string {
return a + b
},
}And hot it's done in cel-go: env, err := cel.NewEnv(
cel.Function("join",
cel.Overload("join_string_string",
[]*cel.Type{cel.StringType, cel.StringType},
cel.StringType,
cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
return types.String(lhs.Value().(string) + rhs.Value().(string))
})))) |
Uh oh!
There was an error while loading. Please reload this page.
I did a benchmark test on several expression parsing libraries, including function calls and injecting structs, and I found that expr's function calls were much slower compared to the other products. I want to figure out the reason for this.
test code
All reactions