mirror of https://github.com/goccy/go-json.git
Merge pull request #100 from goccy/feature/optimize-encoder
Optimize copy of byte slice for encoder
This commit is contained in:
commit
94dcae2d48
20
encode.go
20
encode.go
|
@ -98,6 +98,12 @@ func NewEncoder(w io.Writer) *Encoder {
|
||||||
return enc
|
return enc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newEncoder() *Encoder {
|
||||||
|
enc := encPool.Get().(*Encoder)
|
||||||
|
enc.reset()
|
||||||
|
return enc
|
||||||
|
}
|
||||||
|
|
||||||
// Encode writes the JSON encoding of v to the stream, followed by a newline character.
|
// Encode writes the JSON encoding of v to the stream, followed by a newline character.
|
||||||
//
|
//
|
||||||
// See the documentation for Marshal for details about the conversion of Go values to JSON.
|
// See the documentation for Marshal for details about the conversion of Go values to JSON.
|
||||||
|
@ -172,11 +178,21 @@ func (e *Encoder) encodeForMarshal(header *interfaceHeader, isNil bool) ([]byte,
|
||||||
e.buf = buf
|
e.buf = buf
|
||||||
|
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
copied := make([]byte, len(buf)-2)
|
// this line's description is the below.
|
||||||
|
buf = buf[:len(buf)-2]
|
||||||
|
|
||||||
|
copied := make([]byte, len(buf))
|
||||||
copy(copied, buf)
|
copy(copied, buf)
|
||||||
return copied, nil
|
return copied, nil
|
||||||
}
|
}
|
||||||
copied := make([]byte, len(buf)-1)
|
|
||||||
|
// this line exists to escape call of `runtime.makeslicecopy` .
|
||||||
|
// if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`,
|
||||||
|
// dst buffer size and src buffer size are differrent.
|
||||||
|
// in this case, compiler uses `runtime.makeslicecopy`, but it is slow.
|
||||||
|
buf = buf[:len(buf)-1]
|
||||||
|
|
||||||
|
copied := make([]byte, len(buf))
|
||||||
copy(copied, buf)
|
copy(copied, buf)
|
||||||
return copied, nil
|
return copied, nil
|
||||||
}
|
}
|
||||||
|
|
6
json.go
6
json.go
|
@ -160,8 +160,7 @@ func Marshal(v interface{}) ([]byte, error) {
|
||||||
|
|
||||||
// MarshalNoEscape
|
// MarshalNoEscape
|
||||||
func MarshalNoEscape(v interface{}) ([]byte, error) {
|
func MarshalNoEscape(v interface{}) ([]byte, error) {
|
||||||
var b *bytes.Buffer
|
enc := newEncoder()
|
||||||
enc := NewEncoder(b)
|
|
||||||
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
bytes, err := enc.encodeForMarshal(header, v == nil)
|
bytes, err := enc.encodeForMarshal(header, v == nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -174,8 +173,7 @@ func MarshalNoEscape(v interface{}) ([]byte, error) {
|
||||||
|
|
||||||
// MarshalWithOption returns the JSON encoding of v with EncodeOption.
|
// MarshalWithOption returns the JSON encoding of v with EncodeOption.
|
||||||
func MarshalWithOption(v interface{}, opts ...EncodeOption) ([]byte, error) {
|
func MarshalWithOption(v interface{}, opts ...EncodeOption) ([]byte, error) {
|
||||||
var b *bytes.Buffer
|
enc := newEncoder()
|
||||||
enc := NewEncoder(b)
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(enc); err != nil {
|
if err := opt(enc); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue