Use zero-copy approach to convert types between string and byte… (#2206)

* Use zero-copy approach to convert types between string and byte slice

* Rename argument to a eligible one

Benchmark:

BenchmarkBytesConvBytesToStrRaw-4   	21003800	        70.9 ns/op	      96 B/op	       1 allocs/op
BenchmarkBytesConvBytesToStr-4      	1000000000	         0.333 ns/op	       0 B/op	       0 allocs/op
BenchmarkBytesConvStrToBytesRaw-4   	18478059	        59.3 ns/op	      96 B/op	       1 allocs/op
BenchmarkBytesConvStrToBytes-4      	1000000000	         0.373 ns/op	       0 B/op	       0 allocs/op


Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Andy Pan
2020-01-18 00:32:50 +08:00
committed by Bo-Yi Wu
parent ace6e4c2ea
commit 982daeb1ec
6 changed files with 130 additions and 10 deletions

View File

@ -10,6 +10,7 @@ import (
"html/template"
"net/http"
"github.com/gin-gonic/gin/internal/bytesconv"
"github.com/gin-gonic/gin/internal/json"
)
@ -97,8 +98,9 @@ func (r SecureJSON) Render(w http.ResponseWriter) error {
return err
}
// if the jsonBytes is array values
if bytes.HasPrefix(jsonBytes, []byte("[")) && bytes.HasSuffix(jsonBytes, []byte("]")) {
_, err = w.Write([]byte(r.Prefix))
if bytes.HasPrefix(jsonBytes, bytesconv.StringToBytes("[")) && bytes.HasSuffix(jsonBytes,
bytesconv.StringToBytes("]")) {
_, err = w.Write(bytesconv.StringToBytes(r.Prefix))
if err != nil {
return err
}
@ -126,11 +128,11 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
}
callback := template.JSEscapeString(r.Callback)
_, err = w.Write([]byte(callback))
_, err = w.Write(bytesconv.StringToBytes(callback))
if err != nil {
return err
}
_, err = w.Write([]byte("("))
_, err = w.Write(bytesconv.StringToBytes("("))
if err != nil {
return err
}
@ -138,7 +140,7 @@ func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
if err != nil {
return err
}
_, err = w.Write([]byte(");"))
_, err = w.Write(bytesconv.StringToBytes(");"))
if err != nil {
return err
}
@ -160,7 +162,7 @@ func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
}
var buffer bytes.Buffer
for _, r := range string(ret) {
for _, r := range bytesconv.BytesToString(ret) {
cvt := string(r)
if r >= 128 {
cvt = fmt.Sprintf("\\u%04x", int64(r))