Optimize complex object serialization in source gen

Add WriteObjectGenerated to AcBinarySerializer for direct, efficient serialization of complex objects in source-generated code. Update AcBinarySourceGenerator to use this method, including proper handling of nullable properties, to reduce runtime overhead and avoid unnecessary type dispatch.
This commit is contained in:
Loretta 2026-02-16 13:33:15 +01:00
parent 7284856dda
commit 03f5809e8a
2 changed files with 29 additions and 0 deletions

View File

@ -158,6 +158,15 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
sb.AppendLine($"{i}AcBinarySerializer.WriteStringGenerated({a}, context);");
break;
case PropertyTypeKind.Complex:
// Complex object: use WriteObjectGenerated (skips type dispatch in WriteValueNonPrimitive)
if (p.IsNullable)
{
sb.AppendLine($"{i}if ({a} == null) context.WriteByte(BinaryTypeCode.PropertySkip);");
sb.AppendLine($"{i}else AcBinarySerializer.WriteObjectGenerated({a}, {a}.GetType(), context, depth);");
}
else
sb.AppendLine($"{i}AcBinarySerializer.WriteObjectGenerated({a}, {a}.GetType(), context, depth);");
break;
case PropertyTypeKind.Collection:
if (p.IsNullable)
{

View File

@ -499,6 +499,26 @@ public static partial class AcBinarySerializer
WriteString(value, context);
}
/// <summary>
/// Bridge for generated writers: writes a non-null complex OBJECT directly.
/// Skips WriteValueNonPrimitive type dispatch (is byte[]?, is IDictionary?, is IEnumerable?, GetWrapper)
/// because the SrcGen knows at compile-time that the property is a complex object.
/// Uses pre-resolved wrapper type to avoid GetWrapper dictionary lookup.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void WriteObjectGenerated<TOutput>(object value, Type type, BinarySerializationContext<TOutput> context, int depth)
where TOutput : struct, IBinaryOutputBase
{
if (depth > context.MaxDepth)
{
context.WriteByte(BinaryTypeCode.Null);
return;
}
var wrapper = context.GetWrapper(type);
WriteObject(value, wrapper, context, depth, isNested: depth > 0);
}
#endregion
#region Value Writing