From 78f273a512a7b6585f772e021ad55872ad282938 Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Thu, 8 Dec 2016 08:26:57 +0800 Subject: [PATCH] remove structFieldDecoder --- jsoniter_reflect.go | 114 +++++++++++++++++++++++++-------------- jsoniter_reflect_test.go | 15 +++--- 2 files changed, 80 insertions(+), 49 deletions(-) diff --git a/jsoniter_reflect.go b/jsoniter_reflect.go index 5ad0300..d215457 100644 --- a/jsoniter_reflect.go +++ b/jsoniter_reflect.go @@ -150,16 +150,16 @@ func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { type structDecoder struct { type_ reflect.Type - fields map[string]Decoder + fields map[string]*decodeFieldArgs } func (decoder *structDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { - fieldDecoder := decoder.fields[field] - if fieldDecoder == nil { + args := decoder.fields[field] + if args == nil { iter.Skip() } else { - fieldDecoder.decode(ptr, iter) + decodeField(ptr, iter, field, args.fieldOffset, args.fieldDecoder) } } if iter.Error != nil && iter.Error != io.EOF { @@ -182,12 +182,13 @@ type oneFieldStructDecoder struct { type_ reflect.Type fieldName string fieldDecoder Decoder + fieldOffset uintptr } func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { if field == decoder.fieldName { - decoder.fieldDecoder.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset, decoder.fieldDecoder) } else { iter.Skip() } @@ -201,17 +202,19 @@ type twoFieldsStructDecoder struct { type_ reflect.Type fieldName1 string fieldDecoder1 Decoder + fieldOffset1 uintptr fieldName2 string fieldDecoder2 Decoder + fieldOffset2 uintptr } func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { switch field { case decoder.fieldName1: - decoder.fieldDecoder1.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1) case decoder.fieldName2: - decoder.fieldDecoder2.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2) default: iter.Skip() } @@ -225,21 +228,24 @@ type threeFieldsStructDecoder struct { type_ reflect.Type fieldName1 string fieldDecoder1 Decoder + fieldOffset1 uintptr fieldName2 string fieldDecoder2 Decoder + fieldOffset2 uintptr fieldName3 string fieldDecoder3 Decoder + fieldOffset3 uintptr } func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { switch field { case decoder.fieldName1: - decoder.fieldDecoder1.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1) case decoder.fieldName2: - decoder.fieldDecoder2.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2) case decoder.fieldName3: - decoder.fieldDecoder3.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset3, decoder.fieldDecoder3) default: iter.Skip() } @@ -253,25 +259,29 @@ type fourFieldsStructDecoder struct { type_ reflect.Type fieldName1 string fieldDecoder1 Decoder + fieldOffset1 uintptr fieldName2 string fieldDecoder2 Decoder + fieldOffset2 uintptr fieldName3 string fieldDecoder3 Decoder + fieldOffset3 uintptr fieldName4 string fieldDecoder4 Decoder + fieldOffset4 uintptr } func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { switch field { case decoder.fieldName1: - decoder.fieldDecoder1.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1) case decoder.fieldName2: - decoder.fieldDecoder2.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2) case decoder.fieldName3: - decoder.fieldDecoder3.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset3, decoder.fieldDecoder3) case decoder.fieldName4: - decoder.fieldDecoder4.decode(ptr, iter) + decodeField(ptr, iter, field, decoder.fieldOffset4, decoder.fieldDecoder4) default: iter.Skip() } @@ -281,16 +291,17 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato } } -type structFieldDecoder struct { - field *reflect.StructField +type decodeFieldArgs struct { + fieldOffset uintptr + fieldName string fieldDecoder Decoder } -func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { - fieldPtr := uintptr(ptr) + decoder.field.Offset - decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter) +func decodeField(ptr unsafe.Pointer, iter *Iterator, fieldName string, fieldOffset uintptr, fieldDecoder Decoder) { + fieldPtr := uintptr(ptr) + fieldOffset + fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter) if iter.Error != nil && iter.Error != io.EOF { - iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error()) + iter.Error = fmt.Errorf("%s: %s", fieldName, iter.Error.Error()) } } @@ -538,7 +549,7 @@ func decoderOfOptional(type_ reflect.Type) (Decoder, error) { } func decoderOfStruct(type_ reflect.Type) (Decoder, error) { - fields := map[string]Decoder{} + fields := map[string]*decodeFieldArgs{} for i := 0; i < type_.NumField(); i++ { field := type_.Field(i) fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name) @@ -559,31 +570,36 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { decoder = &stringNumberDecoder{decoder} } if jsonFieldName != "-" { - fields[jsonFieldName] = &structFieldDecoder{&field, decoder} + fields[jsonFieldName] = &decodeFieldArgs{field.Offset, field.Name, decoder} } } switch len(fields) { case 0: return &skipDecoder{type_}, nil case 1: - for fieldName, fieldDecoder := range fields { - return &oneFieldStructDecoder{type_, fieldName, fieldDecoder}, nil + for fieldName, args := range fields { + return &oneFieldStructDecoder{type_, fieldName, args.fieldDecoder, args.fieldOffset}, nil } case 2: var fieldName1 string var fieldName2 string var fieldDecoder1 Decoder var fieldDecoder2 Decoder - for fieldName, fieldDecoder := range fields { + var fieldOffset1 uintptr + var fieldOffset2 uintptr + for fieldName, args := range fields { if fieldName1 == "" { fieldName1 = fieldName - fieldDecoder1 = fieldDecoder + fieldDecoder1 = args.fieldDecoder + fieldOffset1 = args.fieldOffset } else { fieldName2 = fieldName - fieldDecoder2 = fieldDecoder + fieldDecoder2 = args.fieldDecoder + fieldOffset2 = args.fieldOffset } } - return &twoFieldsStructDecoder{type_, fieldName1, fieldDecoder1, fieldName2, fieldDecoder2}, nil + return &twoFieldsStructDecoder{type_, fieldName1, fieldDecoder1, fieldOffset1, + fieldName2, fieldDecoder2, fieldOffset2}, nil case 3: var fieldName1 string var fieldName2 string @@ -591,20 +607,28 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { var fieldDecoder1 Decoder var fieldDecoder2 Decoder var fieldDecoder3 Decoder - for fieldName, fieldDecoder := range fields { + var fieldOffset1 uintptr + var fieldOffset2 uintptr + var fieldOffset3 uintptr + for fieldName, args := range fields { if fieldName1 == "" { fieldName1 = fieldName - fieldDecoder1 = fieldDecoder + fieldDecoder1 = args.fieldDecoder + fieldOffset1 = args.fieldOffset } else if fieldName2 == "" { fieldName2 = fieldName - fieldDecoder2 = fieldDecoder + fieldDecoder2 = args.fieldDecoder + fieldOffset2 = args.fieldOffset } else { fieldName3 = fieldName - fieldDecoder3 = fieldDecoder + fieldDecoder3 = args.fieldDecoder + fieldOffset3 = args.fieldOffset } } return &threeFieldsStructDecoder{type_, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil + fieldName1, fieldDecoder1, fieldOffset1, + fieldName2, fieldDecoder2, fieldOffset2, + fieldName3, fieldDecoder3, fieldOffset3}, nil case 4: var fieldName1 string var fieldName2 string @@ -614,24 +638,34 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) { var fieldDecoder2 Decoder var fieldDecoder3 Decoder var fieldDecoder4 Decoder - for fieldName, fieldDecoder := range fields { + var fieldOffset1 uintptr + var fieldOffset2 uintptr + var fieldOffset3 uintptr + var fieldOffset4 uintptr + for fieldName, args := range fields { if fieldName1 == "" { fieldName1 = fieldName - fieldDecoder1 = fieldDecoder + fieldDecoder1 = args.fieldDecoder + fieldOffset1 = args.fieldOffset } else if fieldName2 == "" { fieldName2 = fieldName - fieldDecoder2 = fieldDecoder + fieldDecoder2 = args.fieldDecoder + fieldOffset2 = args.fieldOffset } else if fieldName3 == "" { fieldName3 = fieldName - fieldDecoder3 = fieldDecoder + fieldDecoder3 = args.fieldDecoder + fieldOffset3 = args.fieldOffset } else { fieldName4 = fieldName - fieldDecoder4 = fieldDecoder + fieldDecoder4 = args.fieldDecoder + fieldOffset4 = args.fieldOffset } } return &fourFieldsStructDecoder{type_, - fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, - fieldName4, fieldDecoder4}, nil + fieldName1, fieldDecoder1, fieldOffset1, + fieldName2, fieldDecoder2, fieldOffset2, + fieldName3, fieldDecoder3, fieldOffset3, + fieldName4, fieldDecoder4, fieldOffset4}, nil } return &structDecoder{type_, fields}, nil } diff --git a/jsoniter_reflect_test.go b/jsoniter_reflect_test.go index 6e031d5..bff5e4b 100644 --- a/jsoniter_reflect_test.go +++ b/jsoniter_reflect_test.go @@ -276,21 +276,18 @@ func Test_reflect_nested(t *testing.T) { type StructOfTagOne struct { - field1 string `json:"field1"` - field2 string `json:"field2"` field3 int `json:"field3,string"` - field4 int `json:"field4,string"` } func Benchmark_jsoniter_reflect(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - //iter := ParseString(`{"field3": "100"}`) - //struct_ := StructOfTagOne{} - //iter.Read(&struct_) - iter := ParseString(`[1,2,3]`) - var array []int - iter.Read(&array) + iter := ParseString(`{"field3": "100"}`) + struct_ := StructOfTagOne{} + iter.Read(&struct_) + //iter := ParseString(`[1,2,3]`) + //var array []int + //iter.Read(&array) } }