Skip to content

[Performance Improvement] Using pool to avoid stack and frames memory allocation #412

@AprilFiv

Description

@AprilFiv

Each time we call NewVM to create a vm instance, as the struct defined, go runtime should apply for a space including the pre-allocated size of [2048]stack and [1024]frames, which may bring us unnecessary overhead in most cases when our script is simple.
I have a proposal to use sync.Pool to reduce such overhead. #413

Benchmark Result

goversion:1.19
goos:darwin
goarch:amd64
BenchmarkTengo/RunWithoutPool
BenchmarkTengo/RunWithoutPool-12         	   64700	     16079 ns/op	   82280 B/op	      10 allocs/op
BenchmarkTengo/RunWithPooled
BenchmarkTengo/RunWithPooled-12          	 2569329	       474.8 ns/op	     369 B/op	       8 allocs/op

Benchmark Code

func BenchmarkTengo(b *testing.B) {

	c := tengo.NewScript([]byte(("res := a + b;")))
	c.Add("a", 10)
	c.Add("b", 10)
	cc, _ := c.Compile()

	b.Run("RunWithoutPool", func(b *testing.B) {
		b.ReportAllocs()
		for i := 0; i < b.N; i++ {
			ccc := cc.Clone()
			ccc.Set("a", 10)
			ccc.Set("b", 10)
			ccc.Run()
		}
	})

	b.Run("RunWithPooled", func(b *testing.B) {
		b.ReportAllocs()
		for i := 0; i < b.N; i++ {
			ccc := cc.Clone()
			ccc.Set("a", 10)
			ccc.Set("b", 10)
			ccc.RunWithStackCache()
		}
	})
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions