Optimize wrapped omitempty operation

This commit is contained in:
Masaaki Goshima 2021-03-20 20:35:44 +09:00
parent dcd9023ac5
commit 906e29acda
6 changed files with 13 additions and 14 deletions

View File

@ -1401,6 +1401,7 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
Indirect: indirect,
Nilcheck: nilcheck,
AddrForMarshaler: addrForMarshaler,
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
}
if fieldIdx == 0 {
fieldCode.HeadIdx = fieldCode.Idx

View File

@ -25,6 +25,7 @@ type Opcode struct {
Indirect bool // whether indirect or not
Nilcheck bool // whether needs to nilcheck or not
AddrForMarshaler bool // whether needs to addr for marshaler or not
IsNextOpPtrType bool // whether next operation is ptr type or not
RshiftNum uint8 // use to take bit for judging whether negative integer or not
Mask uint64 // mask for number
Indent int // indent number
@ -240,6 +241,7 @@ func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode {
Indirect: c.Indirect,
Nilcheck: c.Nilcheck,
AddrForMarshaler: c.AddrForMarshaler,
IsNextOpPtrType: c.IsNextOpPtrType,
Indent: c.Indent,
Idx: c.Idx,
HeadIdx: c.HeadIdx,

View File

@ -5,7 +5,6 @@ import (
"math"
"reflect"
"sort"
"strings"
"unsafe"
"github.com/goccy/go-json/internal/encoder"
@ -623,7 +622,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
b = append(b, '{')
}
p += code.Offset
if p == 0 || (ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr")) {
if p == 0 || (ptrToPtr(p) == 0 && code.IsNextOpPtrType) {
code = code.NextField
} else {
b = append(b, code.Key...)
@ -3119,7 +3118,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmpty:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = append(b, code.Key...)

View File

@ -5,7 +5,6 @@ import (
"math"
"reflect"
"sort"
"strings"
"unsafe"
"github.com/goccy/go-json/internal/encoder"
@ -623,7 +622,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
b = append(b, '{')
}
p += code.Offset
if p == 0 || (ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr")) {
if p == 0 || (ptrToPtr(p) == 0 && code.IsNextOpPtrType) {
code = code.NextField
} else {
b = append(b, code.EscapedKey...)
@ -3119,7 +3118,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmpty:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = append(b, code.EscapedKey...)

View File

@ -6,7 +6,6 @@ import (
"math"
"reflect"
"sort"
"strings"
"unsafe"
"github.com/goccy/go-json/internal/encoder"
@ -641,7 +640,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
b = append(b, '{', '\n')
}
p += code.Offset
if p == 0 || (ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr")) {
if p == 0 || (ptrToPtr(p) == 0 && code.IsNextOpPtrType) {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent+1)
@ -3272,7 +3271,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmpty:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)
@ -4139,7 +4138,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmptyStruct:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)

View File

@ -6,7 +6,6 @@ import (
"math"
"reflect"
"sort"
"strings"
"unsafe"
"github.com/goccy/go-json/internal/encoder"
@ -647,7 +646,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
b = append(b, '{', '\n')
}
p += code.Offset
if p == 0 || (ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr")) {
if p == 0 || (ptrToPtr(p) == 0 && code.IsNextOpPtrType) {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent+1)
@ -3278,7 +3277,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmpty:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)
@ -4145,7 +4144,7 @@ func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, opt
case encoder.OpStructFieldOmitEmptyStruct:
p := load(ctxptr, code.HeadIdx)
p += code.Offset
if ptrToPtr(p) == 0 && strings.Contains(code.Next.Op.String(), "Ptr") {
if ptrToPtr(p) == 0 && code.IsNextOpPtrType {
code = code.NextField
} else {
b = appendIndent(ctx, b, code.Indent)