Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: How to transfer large objects between go and v8 with high performance? #405

Open
zbysir opened this issue Apr 25, 2024 · 0 comments

Comments

@zbysir
Copy link

zbysir commented Apr 25, 2024

My need is to transfer large objects between golang and v8. Usually it has a size of 1M (after Json serialization). I tested using v8.JSONParse() and it will take about 4ms (for 1M json). Is there any way to improve the transfer performance?

Here are some simpler examples and what I tried:

var sampleData = `{
    "root": {
        "id": "lZRRDONbpAi",
        "vid": "lZRRDONbpAi",
        "type": "breakpoint"
    },
    "abc": {
        "id": 1,
        "age": 2
    }
}`

// 3,229 ns/op
func BenchmarkJSONSample(b *testing.B) {
	ctx := v8.NewContext()
	for i := 0; i < b.N; i++ {
		v8.JSONParse(ctx, sampleData)
	}
}

Next I tried initializing the value directly using the v8 api instead of serialization

func toValue(iso *v8.Isolate, pt *v8.ObjectTemplate, ctx *v8.Context, v any) *v8.Value {
	switch v.(type) {
	case string,
		int32,
		uint32,
		int64,
		uint64,
		bool,
		float64:
		x, err := v8.NewValue(iso, v)
		if err != nil {
			panic(err)
		}
		return x
	case map[string]any:
		obj, _ := pt.NewInstance(ctx)
		for k, v := range v.(map[string]any) {
			obj.Set(k, toValue(iso, pt, ctx, v))
		}

		return obj.Value
	default:
		panic(fmt.Sprintf("unsupported type: %T", v))
	}
}
// 18,634 ns/op
// On the contrary, it is slower. I guess it is because c needs to be called multiple times.
func BenchmarkToValueSample(b *testing.B) {
	v := map[string]interface{}{}
	json.Unmarshal([]byte(sampleData), &v)
	ctx := v8.NewContext()
	ot := v8.NewObjectTemplate(ctx.Isolate())
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		toValue(ctx.Isolate(), ot, ctx, v)
	}
}

Is there any way to improve the transfer performance?

I don't know much about cgo vs v8, maybe I'm missing some available API?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant