From 5488fde97f2082db9008f7aabb1d13f864824193 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Tue, 23 May 2017 17:44:50 +0800 Subject: [PATCH] fix one field struct interface{} optimization compatibility --- feature_reflect.go | 12 +- feature_reflect_array.go | 2 +- feature_reflect_native.go | 31 ++-- feature_reflect_object.go | 265 +++++++++++++++++--------------- jsoniter_demo_test.go | 37 ----- jsoniter_reflect_struct_test.go | 20 ++- 6 files changed, 174 insertions(+), 193 deletions(-) diff --git a/feature_reflect.go b/feature_reflect.go index 38b1a30..4b0ab92 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -27,7 +27,7 @@ type Encoder interface { encodeInterface(val interface{}, stream *Stream) } -func WriteToStream(val interface{}, stream *Stream, encoder Encoder) { +func writeToStream(val interface{}, stream *Stream, encoder Encoder) { e := (*emptyInterface)(unsafe.Pointer(&val)) if reflect.TypeOf(val).Kind() == reflect.Ptr { encoder.encode(unsafe.Pointer(&e.word), stream) @@ -57,7 +57,7 @@ func (encoder *funcEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *funcEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *funcEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -193,7 +193,7 @@ func (encoder *optionalEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *optionalEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *optionalEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -213,7 +213,7 @@ func (encoder *placeholderEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *placeholderEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -278,7 +278,7 @@ func (encoder *mapEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *mapEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *mapEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -315,7 +315,7 @@ func (encoder *mapInterfaceEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *mapInterfaceEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *mapInterfaceEncoder) isEmpty(ptr unsafe.Pointer) bool { diff --git a/feature_reflect_array.go b/feature_reflect_array.go index 944a0a0..3bd3f82 100644 --- a/feature_reflect_array.go +++ b/feature_reflect_array.go @@ -53,7 +53,7 @@ func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *sliceEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *sliceEncoder) isEmpty(ptr unsafe.Pointer) bool { diff --git a/feature_reflect_native.go b/feature_reflect_native.go index 6da523f..55cf538 100644 --- a/feature_reflect_native.go +++ b/feature_reflect_native.go @@ -12,11 +12,12 @@ func (codec *stringCodec) decode(ptr unsafe.Pointer, iter *Iterator) { } func (codec *stringCodec) encode(ptr unsafe.Pointer, stream *Stream) { - stream.WriteString(*((*string)(ptr))) + str := *((*string)(ptr)) + stream.WriteString(str) } func (encoder *stringCodec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *stringCodec) isEmpty(ptr unsafe.Pointer) bool { @@ -35,7 +36,7 @@ func (codec *intCodec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *intCodec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *intCodec) isEmpty(ptr unsafe.Pointer) bool { @@ -54,7 +55,7 @@ func (codec *int8Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *int8Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *int8Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -73,7 +74,7 @@ func (codec *int16Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *int16Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *int16Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -92,7 +93,7 @@ func (codec *int32Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *int32Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *int32Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -111,7 +112,7 @@ func (codec *int64Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *int64Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *int64Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -130,7 +131,7 @@ func (codec *uintCodec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *uintCodec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *uintCodec) isEmpty(ptr unsafe.Pointer) bool { @@ -149,7 +150,7 @@ func (codec *uint8Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *uint8Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *uint8Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -168,7 +169,7 @@ func (codec *uint16Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *uint16Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *uint16Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -187,7 +188,7 @@ func (codec *uint32Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *uint32Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *uint32Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -206,7 +207,7 @@ func (codec *uint64Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *uint64Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *uint64Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -225,7 +226,7 @@ func (codec *float32Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *float32Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *float32Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -244,7 +245,7 @@ func (codec *float64Codec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *float64Codec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *float64Codec) isEmpty(ptr unsafe.Pointer) bool { @@ -263,7 +264,7 @@ func (codec *boolCodec) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *boolCodec) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (codec *boolCodec) isEmpty(ptr unsafe.Pointer) bool { diff --git a/feature_reflect_object.go b/feature_reflect_object.go index 1b59984..5dc9125 100644 --- a/feature_reflect_object.go +++ b/feature_reflect_object.go @@ -8,7 +8,6 @@ import ( "strings" ) - func encoderOfStruct(typ reflect.Type) (Encoder, error) { structEncoder_ := &structEncoder{} for i := 0; i < typ.NumField(); i++ { @@ -47,14 +46,9 @@ func encoderOfStruct(typ reflect.Type) (Encoder, error) { return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err) } // map is stored as pointer in the struct - // but if struct only has one map, it is inlined - if field.Type.Kind() == reflect.Map && typ.NumField() > 1 { + if field.Type.Kind() == reflect.Map { encoder = &optionalEncoder{encoder} } - // one field pointer field will be inlined - if field.Type.Kind() == reflect.Ptr && typ.NumField() == 1 { - encoder = (encoder.(*optionalEncoder)).valueEncoder - } } for _, fieldName := range fieldNames { structEncoder_.fields = append(structEncoder_.fields, @@ -180,7 +174,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &threeFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil case 4: var fieldName1 int32 var fieldName2 int32 @@ -213,8 +207,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &fourFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4}, nil case 5: var fieldName1 int32 var fieldName2 int32 @@ -252,8 +246,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &fiveFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil case 6: var fieldName1 int32 var fieldName2 int32 @@ -296,8 +290,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &sixFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil case 7: var fieldName1 int32 var fieldName2 int32 @@ -345,9 +339,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &sevenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7}, nil case 8: var fieldName1 int32 var fieldName2 int32 @@ -400,9 +394,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &eightFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil case 9: var fieldName1 int32 var fieldName2 int32 @@ -460,9 +454,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &nineFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil case 10: var fieldName1 int32 var fieldName2 int32 @@ -525,10 +519,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder } } return &tenFieldsStructDecoder{typ, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, - fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, - fieldName10, fieldDecoder10}, nil + fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10}, nil } return &generalStructDecoder{typ, fields}, nil } @@ -602,11 +596,11 @@ func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) } type twoFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder } func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -632,13 +626,13 @@ func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator } type threeFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder } func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -666,15 +660,15 @@ func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat } type fourFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder } func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -704,17 +698,17 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato } type fiveFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder - fieldHash5 int32 - fieldDecoder5 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder } func (decoder *fiveFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -746,19 +740,19 @@ func (decoder *fiveFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato } type sixFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder - fieldHash5 int32 - fieldDecoder5 *structFieldDecoder - fieldHash6 int32 - fieldDecoder6 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder } func (decoder *sixFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -792,21 +786,21 @@ func (decoder *sixFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator } type sevenFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder - fieldHash5 int32 - fieldDecoder5 *structFieldDecoder - fieldHash6 int32 - fieldDecoder6 *structFieldDecoder - fieldHash7 int32 - fieldDecoder7 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder } func (decoder *sevenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -842,23 +836,23 @@ func (decoder *sevenFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat } type eightFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder - fieldHash5 int32 - fieldDecoder5 *structFieldDecoder - fieldHash6 int32 - fieldDecoder6 *structFieldDecoder - fieldHash7 int32 - fieldDecoder7 *structFieldDecoder - fieldHash8 int32 - fieldDecoder8 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder + fieldHash8 int32 + fieldDecoder8 *structFieldDecoder } func (decoder *eightFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -896,25 +890,25 @@ func (decoder *eightFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterat } type nineFieldsStructDecoder struct { - typ reflect.Type - fieldHash1 int32 - fieldDecoder1 *structFieldDecoder - fieldHash2 int32 - fieldDecoder2 *structFieldDecoder - fieldHash3 int32 - fieldDecoder3 *structFieldDecoder - fieldHash4 int32 - fieldDecoder4 *structFieldDecoder - fieldHash5 int32 - fieldDecoder5 *structFieldDecoder - fieldHash6 int32 - fieldDecoder6 *structFieldDecoder - fieldHash7 int32 - fieldDecoder7 *structFieldDecoder - fieldHash8 int32 - fieldDecoder8 *structFieldDecoder - fieldHash9 int32 - fieldDecoder9 *structFieldDecoder + typ reflect.Type + fieldHash1 int32 + fieldDecoder1 *structFieldDecoder + fieldHash2 int32 + fieldDecoder2 *structFieldDecoder + fieldHash3 int32 + fieldDecoder3 *structFieldDecoder + fieldHash4 int32 + fieldDecoder4 *structFieldDecoder + fieldHash5 int32 + fieldDecoder5 *structFieldDecoder + fieldHash6 int32 + fieldDecoder6 *structFieldDecoder + fieldHash7 int32 + fieldDecoder7 *structFieldDecoder + fieldHash8 int32 + fieldDecoder8 *structFieldDecoder + fieldHash9 int32 + fieldDecoder9 *structFieldDecoder } func (decoder *nineFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { @@ -1045,7 +1039,7 @@ func (encoder *structFieldEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *structFieldEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *structFieldEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -1053,7 +1047,6 @@ func (encoder *structFieldEncoder) isEmpty(ptr unsafe.Pointer) bool { return encoder.fieldEncoder.isEmpty(unsafe.Pointer(fieldPtr)) } - type structEncoder struct { fields []*structFieldEncoder } @@ -1075,7 +1068,24 @@ func (encoder *structEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *structEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + var encoderToUse Encoder + encoderToUse = encoder + if len(encoder.fields) == 1 { + firstEncoder := encoder.fields[0].fieldEncoder + firstEncoderName := reflect.TypeOf(firstEncoder).String() + // interface{} has inline optimization for this case + if firstEncoderName == "*jsoniter.optionalEncoder" { + encoderToUse = &structEncoder{ + fields: []*structFieldEncoder{{ + field: encoder.fields[0].field, + fieldName: encoder.fields[0].fieldName, + fieldEncoder: firstEncoder.(*optionalEncoder).valueEncoder, + omitempty: encoder.fields[0].omitempty, + }}, + } + } + } + writeToStream(val, stream, encoderToUse) } func (encoder *structEncoder) isEmpty(ptr unsafe.Pointer) bool { @@ -1087,7 +1097,6 @@ func (encoder *structEncoder) isEmpty(ptr unsafe.Pointer) bool { return true } - type emptyStructEncoder struct { } @@ -1096,7 +1105,7 @@ func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) { } func (encoder *emptyStructEncoder) encodeInterface(val interface{}, stream *Stream) { - WriteToStream(val, stream, encoder) + writeToStream(val, stream, encoder) } func (encoder *emptyStructEncoder) isEmpty(ptr unsafe.Pointer) bool { diff --git a/jsoniter_demo_test.go b/jsoniter_demo_test.go index 8b5359a..e90502c 100644 --- a/jsoniter_demo_test.go +++ b/jsoniter_demo_test.go @@ -4,8 +4,6 @@ import ( "fmt" "testing" "github.com/json-iterator/go/require" - "unsafe" - "strconv" ) func Test_bind_api_demo(t *testing.T) { @@ -24,38 +22,3 @@ func Test_iterator_api_demo(t *testing.T) { } fmt.Println(total) } - -type DocumentMatch struct { - Index string `json:"index,omitempty"` - ID string `json:"id"` - Score float64 `json:"score"` - Sort []string `json:"sort,omitempty"` -} - -type DocumentMatchCollection []*DocumentMatch - -type SearchResult struct { - Hits DocumentMatchCollection `json:"hits"` -} - -func Test2(t *testing.T) { - RegisterTypeEncoder("float64", func(ptr unsafe.Pointer, stream *Stream) { - t := *((*float64)(ptr)) - stream.WriteRaw(strconv.FormatFloat(t, 'E', -1, 64)) - }) - hits := []byte(`{"hits":[{"index":"geo","id":"firehouse_grill_brewery","score":3.584608106366055e-07, - "sort":[" \u0001@\t\u0007\u0013;a\u001b}W"]}, - {"index":"geo","id":"jack_s_brewing","score":2.3332790568885077e-07, - "sort":[" \u0001@\u0013{w?.\"0\u0010"]}, - {"index":"geo","id":"brewpub_on_the_green","score":2.3332790568885077e-07, - "sort":[" \u0001@\u0014\u0017+\u00137QZG"]}]}`) - var h SearchResult - err := Unmarshal(hits, &h) - fmt.Printf("SR %+v \n", h.Hits[0]) - b, err := Marshal(h.Hits[0]) - if err != nil { - fmt.Printf("error marshalling search res: %v", err) - //return - } - fmt.Printf("SR %s \n", string(b)) -} diff --git a/jsoniter_reflect_struct_test.go b/jsoniter_reflect_struct_test.go index ec14f68..e861cdd 100644 --- a/jsoniter_reflect_struct_test.go +++ b/jsoniter_reflect_struct_test.go @@ -148,7 +148,7 @@ func Test_write_val_one_field_struct(t *testing.T) { func Test_mixed(t *testing.T) { should := require.New(t) - type AA struct { + type AA struct { ID int `json:"id"` Payload map[string]interface{} `json:"payload"` buf *bytes.Buffer `json:"-"` @@ -191,7 +191,7 @@ func Test_recursive_struct(t *testing.T) { should := require.New(t) type TestObject struct { Field1 string - Me *TestObject + Me *TestObject } obj := TestObject{} str, err := MarshalToString(obj) @@ -203,15 +203,23 @@ func Test_recursive_struct(t *testing.T) { func Test_one_field_struct(t *testing.T) { should := require.New(t) + type YetYetAnotherObject struct { + Field string + } + type YetAnotherObject struct { + Field *YetYetAnotherObject + } type AnotherObject struct { + Field *YetAnotherObject } type TestObject struct { Me *AnotherObject } - obj := TestObject{} + obj := TestObject{&AnotherObject{&YetAnotherObject{&YetYetAnotherObject{"abc"}}}} str, err := MarshalToString(obj) should.Nil(err) - should.Equal(`{"Me":{}}`, str) - err = UnmarshalFromString(str, &obj) + should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str) + str, err = MarshalToString(&obj) should.Nil(err) -} \ No newline at end of file + should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str) +}