@@ -145,6 +145,8 @@ public static class CachedDeserializer<T>
145145 private static int _typeId = - 1 ;
146146 private static DeserializeDelegate < T > _deserializer ;
147147 private static DeserializeDelegateRef < T > _deserializerRef ;
148+ private static DeserializeDelegate < T > _optimalDeserializer ;
149+ private static DeserializeDelegateRef < T > _optimalDeserializerRef ;
148150 private static readonly FastMap < int , DeserializeDelegate < T > > SubTypeDeserializers = new ( ) ;
149151 private static readonly FastMap < int , DeserializeDelegateRef < T > > SubTypeDeserializerRefs = new ( ) ;
150152 private static int _singleSubTypeId = int . MinValue ;
@@ -167,11 +169,14 @@ public static class CachedDeserializer<T>
167169 internal static readonly bool IsSimpleType = ! IsReferenceOrContainsReferences && ! HasBaseType ;
168170
169171 public static void SetDeserializer ( int typeId , DeserializeDelegate < T > deserializer ,
170- DeserializeDelegateRef < T > deserializerRef )
172+ DeserializeDelegateRef < T > deserializerRef , DeserializeDelegate < T > optimalDeserializer ,
173+ DeserializeDelegateRef < T > optimalDeserializerRef )
171174 {
172175 _typeId = typeId ;
173176 _deserializer = deserializer ;
174177 _deserializerRef = deserializerRef ;
178+ _optimalDeserializer = optimalDeserializer ;
179+ _optimalDeserializerRef = optimalDeserializerRef ;
175180 SubTypeDeserializers . Add ( typeId , _deserializer ) ;
176181 SubTypeDeserializerRefs . Add ( typeId , _deserializerRef ) ;
177182 _singleSubTypeId = int . MinValue ;
@@ -278,18 +283,15 @@ public static void Deserialize(out T value, ref Reader reader)
278283 return ;
279284 }
280285
281- // FAST PATH 2: JIT-eliminated branch for sealed types
282- // If T is sealed or a value type, it CANNOT have a different runtime type
283- // This completely eliminates polymorphic deserialization overhead
284- if ( IsSealed || SubTypeDeserializers . Count == 1 )
285- {
286- // DIRECT DELEGATE: Generated code path - no polymorphism possible
287- _deserializer ( out value , ref reader ) ;
288- }
289- else
286+ // FAST PATH 1: Optimal serializer for polymorphic usage (with subtypes)
287+ // This is a pre-generated serializer that handles polymorphism internally
288+ if ( _optimalDeserializer != null )
290289 {
291- DeserializePolymorphic ( out value , ref reader ) ;
290+ _optimalDeserializer ( out value , ref reader ) ;
291+ return ;
292292 }
293+
294+ DeserializePolymorphic ( out value , ref reader ) ;
293295 }
294296
295297 // ULTRA-OPTIMIZED: Single core ref method with all paths optimized
@@ -303,23 +305,30 @@ public static void DeserializeRef(ref T value, ref Reader reader)
303305 return ;
304306 }
305307
308+ // FAST PATH 1: Optimal serializer for polymorphic usage (with subtypes)
309+ // This is a pre-generated serializer that handles polymorphism internally
310+ if ( _optimalDeserializerRef != null )
311+ {
312+ _optimalDeserializerRef ( ref value , ref reader ) ;
313+ return ;
314+ }
315+
316+ DeserializeRefPolymorphic ( ref value , ref reader ) ;
317+ }
318+
319+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
320+ public static void DeserializePolymorphic ( out T value , ref Reader reader )
321+ {
306322 // FAST PATH 2: JIT-eliminated branch for sealed types
307323 // If T is sealed or a value type, it CANNOT have a different runtime type
308324 // This completely eliminates polymorphic deserialization overhead
309- if ( IsSealed || SubTypeDeserializerRefs . Count == 1 )
325+ if ( IsSealed || SubTypeDeserializers . Count == 1 )
310326 {
311327 // DIRECT DELEGATE: Generated code path - no polymorphism possible
312- _deserializerRef ( ref value , ref reader ) ;
313- }
314- else
315- {
316- DeserializeRefPolymorphic ( ref value , ref reader ) ;
328+ _deserializer ( out value , ref reader ) ;
329+ return ;
317330 }
318- }
319331
320- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
321- private static void DeserializePolymorphic ( out T value , ref Reader reader )
322- {
323332 // Peek type info for polymorphic types
324333 reader . Peak ( out int typeId ) ;
325334
@@ -364,8 +373,18 @@ private static void DeserializePolymorphic(out T value, ref Reader reader)
364373 }
365374
366375 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
367- private static void DeserializeRefPolymorphic ( ref T value , ref Reader reader )
376+ public static void DeserializeRefPolymorphic ( ref T value , ref Reader reader )
368377 {
378+ // FAST PATH 2: JIT-eliminated branch for sealed types
379+ // If T is sealed or a value type, it CANNOT have a different runtime type
380+ // This completely eliminates polymorphic deserialization overhead
381+ if ( IsSealed || SubTypeDeserializerRefs . Count == 1 )
382+ {
383+ // DIRECT DELEGATE: Generated code path - no polymorphism possible
384+ _deserializerRef ( ref value , ref reader ) ;
385+ return ;
386+ }
387+
369388 // Read type info first for polymorphic types
370389 reader . Peak ( out int typeId ) ;
371390
0 commit comments