Browse Source

c.JSON performance improvement

benchmark                 old ns/op     new ns/op     delta
BenchmarkOneRouteJSON     1143          1053          -7.87%

benchmark                 old allocs     new allocs     delta
BenchmarkOneRouteJSON     4              3              -25.00%

benchmark                 old bytes     new bytes     delta
BenchmarkOneRouteJSON     72            56            -22.22%
Manu Mtz-Almeida 10 years ago
parent
commit
822b995687
2 changed files with 16 additions and 5 deletions
  1. 10 3
      context.go
  2. 6 2
      render/json.go

+ 10 - 3
context.go

@@ -285,11 +285,15 @@ func (c *Context) Header(key, value string) {
 func (c *Context) Render(code int, r render.Render) {
 	c.writermem.WriteHeader(code)
 	if err := r.Render(c.Writer); err != nil {
-		debugPrintError(err)
-		c.AbortWithError(500, err).SetType(ErrorTypeRender)
+		c.renderError(err)
 	}
 }
 
+func (c *Context) renderError(err error) {
+	debugPrintError(err)
+	c.AbortWithError(500, err).SetType(ErrorTypeRender)
+}
+
 // Renders the HTTP template specified by its file name.
 // It also updates the HTTP code and sets the Content-Type as "text/html".
 // See http://golang.org/doc/articles/wiki/
@@ -309,7 +313,10 @@ func (c *Context) IndentedJSON(code int, obj interface{}) {
 // Serializes the given struct as JSON into the response body.
 // It also sets the Content-Type as "application/json".
 func (c *Context) JSON(code int, obj interface{}) {
-	c.Render(code, render.JSON{Data: obj})
+	c.writermem.WriteHeader(code)
+	if err := render.WriteJSON(c.Writer, obj); err != nil {
+		c.renderError(err)
+	}
 }
 
 // Serializes the given struct as XML into the response body.

+ 6 - 2
render/json.go

@@ -22,8 +22,7 @@ type (
 var jsonContentType = []string{"application/json; charset=utf-8"}
 
 func (r JSON) Render(w http.ResponseWriter) error {
-	w.Header()["Content-Type"] = jsonContentType
-	return json.NewEncoder(w).Encode(r.Data)
+	return WriteJSON(w, r.Data)
 }
 
 func (r IndentedJSON) Render(w http.ResponseWriter) error {
@@ -35,3 +34,8 @@ func (r IndentedJSON) Render(w http.ResponseWriter) error {
 	w.Write(jsonBytes)
 	return nil
 }
+
+func WriteJSON(w http.ResponseWriter, obj interface{}) error {
+	w.Header()["Content-Type"] = jsonContentType
+	return json.NewEncoder(w).Encode(obj)
+}