带有 `.SetEscapeHTML(true)`的`.Encode`特别慢(比标准库慢20倍)
chyroc opened this issue · 1 comments
chyroc commented
事情是这样的,我想在 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
不知道你们有空吗,可以抽空看一下吗,多谢啦~
taowen commented
是因为 SetEscapeHTML 内部创建了新的config,但是没有cache的原因。这个 commit json-iterator/go@ee8cfb7 修复了