1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-23 18:54:21 +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_ 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
}

View File

@ -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)
}
}