From 807e4a8b20486bd718a07c9f4194e398b4d67733 Mon Sep 17 00:00:00 2001 From: Matt Good Date: Mon, 22 Jan 2018 14:03:50 -0800 Subject: [PATCH] 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. --- feature_reflect_array.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/feature_reflect_array.go b/feature_reflect_array.go index 7eb2af9..a6dd91c 100644 --- a/feature_reflect_array.go +++ b/feature_reflect_array.go @@ -13,6 +13,9 @@ func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecod } func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder { + if typ.Len() == 0 { + return emptyArrayEncoder{} + } encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem()) if typ.Elem().Kind() == reflect.Map { encoder = &OptionalEncoder{encoder} @@ -20,6 +23,20 @@ func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncod 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 { arrayType reflect.Type elemType reflect.Type @@ -27,10 +44,6 @@ type arrayEncoder struct { } func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { - if encoder.arrayType.Len() == 0 { - stream.WriteEmptyArray() - return - } stream.WriteArrayStart() elemPtr := unsafe.Pointer(ptr) encoder.elemEncoder.Encode(elemPtr, stream)