diff --git a/render/json.go b/render/json.go index fc8dea45..d8de81e3 100644 --- a/render/json.go +++ b/render/json.go @@ -52,6 +52,11 @@ var ( jsonASCIIContentType = []string{"application/json"} ) +var ( + leftSquareBracket = bytesconv.StringToBytes("[") + rightSquareBracket = bytesconv.StringToBytes("]") +) + // Render (JSON) writes data with custom ContentType. func (r JSON) Render(w http.ResponseWriter) error { return WriteJSON(w, r.Data) @@ -97,11 +102,8 @@ func (r SecureJSON) Render(w http.ResponseWriter) error { return err } // if the jsonBytes is array values - if bytes.HasPrefix(jsonBytes, bytesconv.StringToBytes("[")) && bytes.HasSuffix(jsonBytes, - bytesconv.StringToBytes("]")) { - if _, err = w.Write(bytesconv.StringToBytes(r.Prefix)); err != nil { - return err - } + if bytes.HasPrefix(jsonBytes, leftSquareBracket) && bytes.HasSuffix(jsonBytes, rightSquareBracket) { + jsonBytes = append(bytesconv.StringToBytes(r.Prefix), jsonBytes...) } _, err = w.Write(jsonBytes) return err @@ -124,25 +126,8 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) { _, err = w.Write(ret) return err } - - callback := template.JSEscapeString(r.Callback) - if _, err = w.Write(bytesconv.StringToBytes(callback)); err != nil { - return err - } - - if _, err = w.Write(bytesconv.StringToBytes("(")); err != nil { - return err - } - - if _, err = w.Write(ret); err != nil { - return err - } - - if _, err = w.Write(bytesconv.StringToBytes(");")); err != nil { - return err - } - - return nil + _, err = w.Write(bytesconv.StringToBytes(template.JSEscapeString(r.Callback) + "(" + bytesconv.BytesToString(ret) + ");")) + return err } // WriteContentType (JsonpJSON) writes Javascript ContentType. @@ -160,11 +145,11 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) { var buffer bytes.Buffer for _, r := range bytesconv.BytesToString(ret) { - cvt := string(r) if r >= 128 { - cvt = fmt.Sprintf("\\u%04x", int64(r)) + buffer.WriteString(fmt.Sprintf("\\u%04x", r)) + } else { + buffer.WriteByte(byte(r)) } - buffer.WriteString(cvt) } _, err = w.Write(buffer.Bytes()) diff --git a/render/render_test.go b/render/render_test.go index 86dc362d..f469c109 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -578,3 +578,33 @@ func TestRenderReaderNoContentLength(t *testing.T) { assert.Equal(t, headers["Content-Disposition"], w.Header().Get("Content-Disposition")) assert.Equal(t, headers["x-request-id"], w.Header().Get("x-request-id")) } + +func BenchmarkAsciiJSONRender(b *testing.B) { + data := getRenderData() + benchmarkRender(b, AsciiJSON{Data: data}) +} + +func BenchmarkJsonpJSONRender(b *testing.B) { + data := getRenderData() + benchmarkRender(b, JsonpJSON{Data: data}) +} + +func benchmarkRender(b *testing.B, r Render) { + w := httptest.NewRecorder() + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + err := r.Render(w) + if err != nil { + b.Errorf("test json render error =>%v", err) + } + } +} + +func getRenderData() map[string]any { + data := map[string]any{ + "cn": "

你好 世界

", + "en": "

hello world

", + } + return data +}