Quellcode durchsuchen

remove structFieldDecoder

Tao Wen vor 9 Jahren
Ursprung
Commit
78f273a512
2 geänderte Dateien mit 80 neuen und 49 gelöschten Zeilen
  1. 74 40
      jsoniter_reflect.go
  2. 6 9
      jsoniter_reflect_test.go

+ 74 - 40
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
 }

+ 6 - 9
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)
 	}
 }