Optimize scan codegen with compile-time property checks

Added HasScanWork and related methods to determine at compile time if a property requires scan work. EmitScanProp now skips code generation for properties proven to not need scan logic, improving efficiency and reducing unnecessary code output.
This commit is contained in:
Loretta 2026-03-10 18:35:25 +01:00
parent 2f99b4e3b7
commit 16daad2917
1 changed files with 34 additions and 0 deletions

View File

@ -835,6 +835,37 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
/// Emits direct object write — bypasses GetWrapper + WriteObject entirely.
#region Scan Pass Code Generation
/// <summary>
/// Compile-time check: will EmitScanProp produce any scan work for this property?
/// When false, the entire block (including PropertyFilter guard) is skipped.
/// </summary>
private static bool HasScanWork(PropInfo p) => p.TypeKind switch
{
PropertyTypeKind.String => p.InterningFlags != 0,
PropertyTypeKind.Complex when p.HasGeneratedWriter => p.ChildNeedsScan,
PropertyTypeKind.Complex => true,
PropertyTypeKind.Collection => HasCollectionScanWork(p),
PropertyTypeKind.Dictionary => HasDictionaryScanWork(p),
_ => false
};
private static bool HasCollectionScanWork(PropInfo p) => p.ElementKind switch
{
PropertyTypeKind.String => p.InterningFlags != 0,
PropertyTypeKind.Complex when p.ElementHasGeneratedWriter && p.CollectionKind != null => p.ElementNeedsScan,
PropertyTypeKind.Complex => true,
_ => false
};
private static bool HasDictionaryScanWork(PropInfo p)
{
if (p.DictKeyKind == PropertyTypeKind.String && p.InterningFlags != 0) return true;
if (p.DictValueKind == PropertyTypeKind.String && p.InterningFlags != 0) return true;
if (p.DictValueKind == PropertyTypeKind.Complex && p.DictValueHasGeneratedWriter) return p.DictValueNeedsScan;
if (p.DictValueKind == PropertyTypeKind.Complex) return true;
return false;
}
/// <summary>
/// Emits scan pass code for a single property.
/// String: interning check + ScanInternString.
@ -844,6 +875,9 @@ public class AcBinarySourceGenerator : IIncrementalGenerator
/// </summary>
private static void EmitScanProp(StringBuilder sb, PropInfo p, string i, string fullTypeName)
{
// Compile-time proven: no scan work for this property — skip entirely (including PropertyFilter guard)
if (!HasScanWork(p)) return;
var a = $"obj.{p.Name}";
// PropertyFilter: must match write pass — if filter skips property, scan must skip too