Przeglądaj źródła

fix one field struct interface{} optimization compatibility

Tao Wen 8 lat temu
rodzic
commit
5488fde97f

+ 6 - 6
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 {

+ 1 - 1
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 {

+ 16 - 15
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 {

+ 137 - 128
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 {

+ 0 - 37
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))
-}

+ 14 - 6
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)
-}
+	should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str)
+}