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:
parent
7284856dda
commit
03f5809e8a
|
|
@ -158,6 +158,15 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
|
||||||
sb.AppendLine($"{i}AcBinarySerializer.WriteStringGenerated({a}, context);");
|
sb.AppendLine($"{i}AcBinarySerializer.WriteStringGenerated({a}, context);");
|
||||||
break;
|
break;
|
||||||
case PropertyTypeKind.Complex:
|
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:
|
case PropertyTypeKind.Collection:
|
||||||
if (p.IsNullable)
|
if (p.IsNullable)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -499,6 +499,26 @@ public static partial class AcBinarySerializer
|
||||||
WriteString(value, context);
|
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
|
#endregion
|
||||||
|
|
||||||
#region Value Writing
|
#region Value Writing
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue