1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-23 11:37:32 +02:00

remove structFieldDecoder

This commit is contained in:
Tao Wen 2016-12-08 08:26:57 +08:00
parent 3e376c671c
commit 78f273a512
2 changed files with 80 additions and 49 deletions

View File

@ -150,16 +150,16 @@ func (decoder *optionalDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
type structDecoder struct { type structDecoder struct {
type_ reflect.Type type_ reflect.Type
fields map[string]Decoder fields map[string]*decodeFieldArgs
} }
func (decoder *structDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *structDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
fieldDecoder := decoder.fields[field] args := decoder.fields[field]
if fieldDecoder == nil { if args == nil {
iter.Skip() iter.Skip()
} else { } else {
fieldDecoder.decode(ptr, iter) decodeField(ptr, iter, field, args.fieldOffset, args.fieldDecoder)
} }
} }
if iter.Error != nil && iter.Error != io.EOF { if iter.Error != nil && iter.Error != io.EOF {
@ -182,12 +182,13 @@ type oneFieldStructDecoder struct {
type_ reflect.Type type_ reflect.Type
fieldName string fieldName string
fieldDecoder Decoder fieldDecoder Decoder
fieldOffset uintptr
} }
func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *oneFieldStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
if field == decoder.fieldName { if field == decoder.fieldName {
decoder.fieldDecoder.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset, decoder.fieldDecoder)
} else { } else {
iter.Skip() iter.Skip()
} }
@ -201,17 +202,19 @@ type twoFieldsStructDecoder struct {
type_ reflect.Type type_ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 Decoder fieldDecoder1 Decoder
fieldOffset1 uintptr
fieldName2 string fieldName2 string
fieldDecoder2 Decoder fieldDecoder2 Decoder
fieldOffset2 uintptr
} }
func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *twoFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1)
case decoder.fieldName2: case decoder.fieldName2:
decoder.fieldDecoder2.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2)
default: default:
iter.Skip() iter.Skip()
} }
@ -225,21 +228,24 @@ type threeFieldsStructDecoder struct {
type_ reflect.Type type_ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 Decoder fieldDecoder1 Decoder
fieldOffset1 uintptr
fieldName2 string fieldName2 string
fieldDecoder2 Decoder fieldDecoder2 Decoder
fieldOffset2 uintptr
fieldName3 string fieldName3 string
fieldDecoder3 Decoder fieldDecoder3 Decoder
fieldOffset3 uintptr
} }
func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *threeFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1)
case decoder.fieldName2: case decoder.fieldName2:
decoder.fieldDecoder2.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2)
case decoder.fieldName3: case decoder.fieldName3:
decoder.fieldDecoder3.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset3, decoder.fieldDecoder3)
default: default:
iter.Skip() iter.Skip()
} }
@ -253,25 +259,29 @@ type fourFieldsStructDecoder struct {
type_ reflect.Type type_ reflect.Type
fieldName1 string fieldName1 string
fieldDecoder1 Decoder fieldDecoder1 Decoder
fieldOffset1 uintptr
fieldName2 string fieldName2 string
fieldDecoder2 Decoder fieldDecoder2 Decoder
fieldOffset2 uintptr
fieldName3 string fieldName3 string
fieldDecoder3 Decoder fieldDecoder3 Decoder
fieldOffset3 uintptr
fieldName4 string fieldName4 string
fieldDecoder4 Decoder fieldDecoder4 Decoder
fieldOffset4 uintptr
} }
func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
switch field { switch field {
case decoder.fieldName1: case decoder.fieldName1:
decoder.fieldDecoder1.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset1, decoder.fieldDecoder1)
case decoder.fieldName2: case decoder.fieldName2:
decoder.fieldDecoder2.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset2, decoder.fieldDecoder2)
case decoder.fieldName3: case decoder.fieldName3:
decoder.fieldDecoder3.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset3, decoder.fieldDecoder3)
case decoder.fieldName4: case decoder.fieldName4:
decoder.fieldDecoder4.decode(ptr, iter) decodeField(ptr, iter, field, decoder.fieldOffset4, decoder.fieldDecoder4)
default: default:
iter.Skip() iter.Skip()
} }
@ -281,16 +291,17 @@ func (decoder *fourFieldsStructDecoder) decode(ptr unsafe.Pointer, iter *Iterato
} }
} }
type structFieldDecoder struct { type decodeFieldArgs struct {
field *reflect.StructField fieldOffset uintptr
fieldName string
fieldDecoder Decoder fieldDecoder Decoder
} }
func (decoder *structFieldDecoder) decode(ptr unsafe.Pointer, iter *Iterator) { func decodeField(ptr unsafe.Pointer, iter *Iterator, fieldName string, fieldOffset uintptr, fieldDecoder Decoder) {
fieldPtr := uintptr(ptr) + decoder.field.Offset fieldPtr := uintptr(ptr) + fieldOffset
decoder.fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter) fieldDecoder.decode(unsafe.Pointer(fieldPtr), iter)
if iter.Error != nil && iter.Error != io.EOF { 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) { func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
fields := map[string]Decoder{} fields := map[string]*decodeFieldArgs{}
for i := 0; i < type_.NumField(); i++ { for i := 0; i < type_.NumField(); i++ {
field := type_.Field(i) field := type_.Field(i)
fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name) fieldDecoderKey := fmt.Sprintf("%s/%s", type_.String(), field.Name)
@ -559,31 +570,36 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
decoder = &stringNumberDecoder{decoder} decoder = &stringNumberDecoder{decoder}
} }
if jsonFieldName != "-" { if jsonFieldName != "-" {
fields[jsonFieldName] = &structFieldDecoder{&field, decoder} fields[jsonFieldName] = &decodeFieldArgs{field.Offset, field.Name, decoder}
} }
} }
switch len(fields) { switch len(fields) {
case 0: case 0:
return &skipDecoder{type_}, nil return &skipDecoder{type_}, nil
case 1: case 1:
for fieldName, fieldDecoder := range fields { for fieldName, args := range fields {
return &oneFieldStructDecoder{type_, fieldName, fieldDecoder}, nil return &oneFieldStructDecoder{type_, fieldName, args.fieldDecoder, args.fieldOffset}, nil
} }
case 2: case 2:
var fieldName1 string var fieldName1 string
var fieldName2 string var fieldName2 string
var fieldDecoder1 Decoder var fieldDecoder1 Decoder
var fieldDecoder2 Decoder var fieldDecoder2 Decoder
for fieldName, fieldDecoder := range fields { var fieldOffset1 uintptr
var fieldOffset2 uintptr
for fieldName, args := range fields {
if fieldName1 == "" { if fieldName1 == "" {
fieldName1 = fieldName fieldName1 = fieldName
fieldDecoder1 = fieldDecoder fieldDecoder1 = args.fieldDecoder
fieldOffset1 = args.fieldOffset
} else { } else {
fieldName2 = fieldName 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: case 3:
var fieldName1 string var fieldName1 string
var fieldName2 string var fieldName2 string
@ -591,20 +607,28 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
var fieldDecoder1 Decoder var fieldDecoder1 Decoder
var fieldDecoder2 Decoder var fieldDecoder2 Decoder
var fieldDecoder3 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 == "" { if fieldName1 == "" {
fieldName1 = fieldName fieldName1 = fieldName
fieldDecoder1 = fieldDecoder fieldDecoder1 = args.fieldDecoder
fieldOffset1 = args.fieldOffset
} else if fieldName2 == "" { } else if fieldName2 == "" {
fieldName2 = fieldName fieldName2 = fieldName
fieldDecoder2 = fieldDecoder fieldDecoder2 = args.fieldDecoder
fieldOffset2 = args.fieldOffset
} else { } else {
fieldName3 = fieldName fieldName3 = fieldName
fieldDecoder3 = fieldDecoder fieldDecoder3 = args.fieldDecoder
fieldOffset3 = args.fieldOffset
} }
} }
return &threeFieldsStructDecoder{type_, return &threeFieldsStructDecoder{type_,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil fieldName1, fieldDecoder1, fieldOffset1,
fieldName2, fieldDecoder2, fieldOffset2,
fieldName3, fieldDecoder3, fieldOffset3}, nil
case 4: case 4:
var fieldName1 string var fieldName1 string
var fieldName2 string var fieldName2 string
@ -614,24 +638,34 @@ func decoderOfStruct(type_ reflect.Type) (Decoder, error) {
var fieldDecoder2 Decoder var fieldDecoder2 Decoder
var fieldDecoder3 Decoder var fieldDecoder3 Decoder
var fieldDecoder4 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 == "" { if fieldName1 == "" {
fieldName1 = fieldName fieldName1 = fieldName
fieldDecoder1 = fieldDecoder fieldDecoder1 = args.fieldDecoder
fieldOffset1 = args.fieldOffset
} else if fieldName2 == "" { } else if fieldName2 == "" {
fieldName2 = fieldName fieldName2 = fieldName
fieldDecoder2 = fieldDecoder fieldDecoder2 = args.fieldDecoder
fieldOffset2 = args.fieldOffset
} else if fieldName3 == "" { } else if fieldName3 == "" {
fieldName3 = fieldName fieldName3 = fieldName
fieldDecoder3 = fieldDecoder fieldDecoder3 = args.fieldDecoder
fieldOffset3 = args.fieldOffset
} else { } else {
fieldName4 = fieldName fieldName4 = fieldName
fieldDecoder4 = fieldDecoder fieldDecoder4 = args.fieldDecoder
fieldOffset4 = args.fieldOffset
} }
} }
return &fourFieldsStructDecoder{type_, return &fourFieldsStructDecoder{type_,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3, fieldName1, fieldDecoder1, fieldOffset1,
fieldName4, fieldDecoder4}, nil fieldName2, fieldDecoder2, fieldOffset2,
fieldName3, fieldDecoder3, fieldOffset3,
fieldName4, fieldDecoder4, fieldOffset4}, nil
} }
return &structDecoder{type_, fields}, nil return &structDecoder{type_, fields}, nil
} }

View File

@ -276,21 +276,18 @@ func Test_reflect_nested(t *testing.T) {
type StructOfTagOne struct { type StructOfTagOne struct {
field1 string `json:"field1"`
field2 string `json:"field2"`
field3 int `json:"field3,string"` field3 int `json:"field3,string"`
field4 int `json:"field4,string"`
} }
func Benchmark_jsoniter_reflect(b *testing.B) { func Benchmark_jsoniter_reflect(b *testing.B) {
b.ReportAllocs() b.ReportAllocs()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
//iter := ParseString(`{"field3": "100"}`) iter := ParseString(`{"field3": "100"}`)
//struct_ := StructOfTagOne{} struct_ := StructOfTagOne{}
//iter.Read(&struct_) iter.Read(&struct_)
iter := ParseString(`[1,2,3]`) //iter := ParseString(`[1,2,3]`)
var array []int //var array []int
iter.Read(&array) //iter.Read(&array)
} }
} }