From 906e29acda8ec74575d6ec73bd6e32dae8cd582f Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Sat, 20 Mar 2021 20:35:44 +0900 Subject: [PATCH] Optimize wrapped omitempty operation --- internal/encoder/compiler.go | 1 + internal/encoder/opcode.go | 2 ++ internal/encoder/vm/vm.go | 5 ++--- internal/encoder/vm_escaped/vm.go | 5 ++--- internal/encoder/vm_escaped_indent/vm.go | 7 +++---- internal/encoder/vm_indent/vm.go | 7 +++---- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go index fb86695..214382c 100644 --- a/internal/encoder/compiler.go +++ b/internal/encoder/compiler.go @@ -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 diff --git a/internal/encoder/opcode.go b/internal/encoder/opcode.go index 875d4b2..943f8b3 100644 --- a/internal/encoder/opcode.go +++ b/internal/encoder/opcode.go @@ -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, diff --git a/internal/encoder/vm/vm.go b/internal/encoder/vm/vm.go index 3ce0300..9906515 100644 --- a/internal/encoder/vm/vm.go +++ b/internal/encoder/vm/vm.go @@ -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...) diff --git a/internal/encoder/vm_escaped/vm.go b/internal/encoder/vm_escaped/vm.go index 563db6d..df7cd97 100644 --- a/internal/encoder/vm_escaped/vm.go +++ b/internal/encoder/vm_escaped/vm.go @@ -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...) diff --git a/internal/encoder/vm_escaped_indent/vm.go b/internal/encoder/vm_escaped_indent/vm.go index 02af6d3..e70d3b3 100644 --- a/internal/encoder/vm_escaped_indent/vm.go +++ b/internal/encoder/vm_escaped_indent/vm.go @@ -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) diff --git a/internal/encoder/vm_indent/vm.go b/internal/encoder/vm_indent/vm.go index c3e54cc..a4dd4b7 100644 --- a/internal/encoder/vm_indent/vm.go +++ b/internal/encoder/vm_indent/vm.go @@ -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)