1
0
mirror of https://github.com/json-iterator/go.git synced 2025-06-24 23:16:47 +02:00

Optimize 0-length array case

Instead of checking the array length in encode, this can be checked up
front in `encoderOfArray` since the array type has a fixed length
determined at compile time. So return an `emptyArrayEncoder` that simply
writes an empty array to the stream.
This commit is contained in:
Matt Good
2018-01-22 14:03:50 -08:00
parent ba3857729b
commit 807e4a8b20

View File

@ -13,6 +13,9 @@ func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecod
} }
func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder { func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
if typ.Len() == 0 {
return emptyArrayEncoder{}
}
encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem()) encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem())
if typ.Elem().Kind() == reflect.Map { if typ.Elem().Kind() == reflect.Map {
encoder = &OptionalEncoder{encoder} encoder = &OptionalEncoder{encoder}
@ -20,6 +23,20 @@ func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncod
return &arrayEncoder{typ, typ.Elem(), encoder} return &arrayEncoder{typ, typ.Elem(), encoder}
} }
type emptyArrayEncoder struct{}
func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteEmptyArray()
}
func (encoder emptyArrayEncoder) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteEmptyArray()
}
func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return true
}
type arrayEncoder struct { type arrayEncoder struct {
arrayType reflect.Type arrayType reflect.Type
elemType reflect.Type elemType reflect.Type
@ -27,10 +44,6 @@ type arrayEncoder struct {
} }
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if encoder.arrayType.Len() == 0 {
stream.WriteEmptyArray()
return
}
stream.WriteArrayStart() stream.WriteArrayStart()
elemPtr := unsafe.Pointer(ptr) elemPtr := unsafe.Pointer(ptr)
encoder.elemEncoder.Encode(elemPtr, stream) encoder.elemEncoder.Encode(elemPtr, stream)