json-iterator/go-benchmark

带有 `.SetEscapeHTML(true)`的`.Encode`特别慢(比标准库慢20倍)

chyroc opened this issue · 1 comments

事情是这样的,我想在 https://github.com/go-chi/render 中将json库替换为你们写的json库:go-chi/render#11 (通过build tag方式),然后今天写了一下benchmark,发现带有.SetEscapeHTML(true).Encode特别慢。
测试代码:

package test

import (
	"bytes"
	"testing"
	"encoding/json"

	"github.com/json-iterator/go"
)

type V struct {
	S string
	B bool
	I int
}

func BenchmarkTestStdEncode(b *testing.B) {
	for i := 0; i < b.N; i++ {
		buf := &bytes.Buffer{}
		enc := json.NewEncoder(buf)
		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
			b.Fatal(err)
		}
	}
}

func BenchmarkTestStdEncodeWithSetEscapeHTML(b *testing.B) {
	for i := 0; i < b.N; i++ {
		buf := &bytes.Buffer{}
		enc := json.NewEncoder(buf)
		enc.SetEscapeHTML(true)
		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
			b.Fatal(err)
		}
	}
}

func BenchmarkTestIteratorEncode(b *testing.B) {
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	for i := 0; i < b.N; i++ {
		buf := &bytes.Buffer{}
		enc := json.NewEncoder(buf)
		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
			b.Fatal(err)
		}
	}
}

func BenchmarkTestIteratorEncodeWithSetEscapeHTML(b *testing.B) {
	var json = jsoniter.ConfigCompatibleWithStandardLibrary
	for i := 0; i < b.N; i++ {
		buf := &bytes.Buffer{}
		enc := json.NewEncoder(buf)
		enc.SetEscapeHTML(true)
		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
			b.Fatal(err)
		}
	}
}

测试结果

➜  go test github.com/go-chi/render/test -bench='.'
goos: darwin
goarch: amd64
pkg: github.com/go-chi/render/test
BenchmarkTestStdEncode-8                         	 3000000	       551 ns/op
BenchmarkTestStdEncodeWithSetEscapeHTML-8        	 3000000	       550 ns/op
BenchmarkTestIteratorEncode-8                    	 3000000	       566 ns/op
BenchmarkTestIteratorEncodeWithSetEscapeHTML-8   	  200000	     10698 ns/op
PASS
ok  	github.com/go-chi/render/test	8.969s

不知道你们有空吗,可以抽空看一下吗,多谢啦~

是因为 SetEscapeHTML 内部创建了新的config,但是没有cache的原因。这个 commit json-iterator/go@ee8cfb7 修复了