Skip to content

Why is the function call speed of expr very slow #300

@p1g3

Description

@p1g3

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.

$ go test -bench=. -benchtime=10s
goos: darwin
goarch: amd64
pkg: github.com/antonmedv/golang-expression-evaluation-comparison
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Benchmark_bexpr-12                 	 5676273	      2089 ns/op
Benchmark_celgo-12                 	77683569	       153.0 ns/op
Benchmark_celgo_startswith-12      	42621015	       278.7 ns/op
Benchmark_celgo_funccall-12        	69535796	       172.7 ns/op
Benchmark_celgo_struct-12          	16101632	       748.2 ns/op
Benchmark_evalfilter-12            	 7971537	      1508 ns/op
Benchmark_expr-12                  	93287458	       126.6 ns/op
Benchmark_expr_startswith-12       	48665090	       246.6 ns/op
Benchmark_expr_funccall-12         	22060058	       544.6 ns/op
Benchmark_expr_struct-12           	39742920	       300.1 ns/op
Benchmark_goja-12                  	41479744	       286.4 ns/op
Benchmark_govaluate-12             	55276390	       213.1 ns/op
Benchmark_govaluate_funccall-12    	87888637	       125.8 ns/op
Benchmark_govaluate_struct-12      	19006689	       629.2 ns/op
Benchmark_gval-12                  	20624302	       579.2 ns/op
Benchmark_otto-12                  	19031895	       630.9 ns/op
Benchmark_starlark-12              	 2717073	      4394 ns/op
PASS
ok  	github.com/antonmedv/golang-expression-evaluation-comparison	215.618s

test code

func Benchmark_expr_funccall(b *testing.B) {
	params := map[string]interface{}{
		"hello": func(str string) string { return "hello " + str },
	}

	program, err := expr.Compile(`hello("world")`)
	if err != nil {
		b.Fatal(err)
	}

	var out interface{}

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		out, err = expr.Run(program, params)
	}
	b.StopTimer()

	if err != nil {
		b.Fatal(err)
	}
	if out.(string) != "hello world" {
		b.Fail()
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions