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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions