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, Indirect: indirect,
Nilcheck: nilcheck, Nilcheck: nilcheck,
AddrForMarshaler: addrForMarshaler, AddrForMarshaler: addrForMarshaler,
IsNextOpPtrType: strings.Contains(valueCode.Op.String(), "Ptr"),
} }
if fieldIdx == 0 { if fieldIdx == 0 {
fieldCode.HeadIdx = fieldCode.Idx fieldCode.HeadIdx = fieldCode.Idx

View File

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

View File

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

View File

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

View File

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

View File

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