From 7e2478f3947c1721619341d702152365ba5581ae Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Tue, 12 Jul 2022 13:13:12 -0700 Subject: [PATCH] Immediately filter syntax trees down to those that either have attributes or global-using-aliases. (#62483) * Cache the hash in compilation options * Remove * Update src/Compilers/Core/Portable/InternalUtilities/Hash.cs * Update src/Compilers/Core/Portable/InternalUtilities/Hash.cs * Update src/Compilers/Core/Portable/InternalUtilities/Hash.cs * Fix api * Walk green-nodes in incremental-generator attribute-finding path * Use green nodes * REmove * Fix tests * Avoid allocating builder if not needed * Simplify * Only loop once * Do not look for load/reference directives when there can't be any * REmove use of Lazy in DeclarationTable for rarely used values. * Remove lazy * In progress * Change the data-flow path for searching for attributes to prevent fewer intermediary tables. * Remove unused type * Simplify * Update tests * Make internal * Update * Update src/Compilers/Core/Portable/SourceGeneration/Nodes/NodeStateTable.cs * Update comment * Filter large tables before processing htem. * Update tests * Sort * Fix grammar * Fix assert * Add back in * Revert * Simplify * remove * Simplify * Remove * Simplify global aliases * Prefilter to only trees that have attributes or globalaliases in them * INcrease * Only check the top level for global usings. * Remove comment * Simplify * Add docs * Revert * Make static * Extract common code * PR feedback * Use helper * update run counts * Chain compilations * Fix grammar * Don't use implicit construction * Fix * Tweak benchmark * Simplify walk --- ...iverTests_Attributes_FullyQualifiedName.cs | 15 ++-- ...eratorDriverTests_Attributes_SimpleName.cs | 22 +++--- .../SourceGeneration/StateTableTests.cs | 2 +- .../SourceGeneration/GlobalAliases.cs | 16 ++++ .../SourceGeneration/Nodes/NodeStateTable.cs | 9 ++- ...alueProvider_ForAttributeWithSimpleName.cs | 74 +++++++++++++------ ...iverTests_Attributes_FullyQualifiedName.vb | 15 ++-- ...eratorDriverTests_Attributes_SimpleName.vb | 5 +- .../IncrementalSourceGeneratorBenchmarks.cs | 12 +-- 9 files changed, 103 insertions(+), 67 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.cs index 07dd13aed7272..cb56f20febbb4 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.cs @@ -1373,8 +1373,7 @@ class XAttribute : System.Attribute Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason); @@ -1419,8 +1418,7 @@ class XAttribute : System.Attribute Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason); @@ -1469,8 +1467,7 @@ class XAttribute : System.Attribute Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs, t => Assert.Equal(IncrementalStepRunReason.Cached, t.Reason)); @@ -1522,8 +1519,7 @@ class XAttribute : System.Attribute Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); Assert.Collection(runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"], s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason), s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason)); @@ -1633,8 +1629,7 @@ class C { } Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttributeInternal"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationAndGroupedNodes_ForAttributeWithMetadataName"].Single().Outputs.Single().Reason); diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.cs index 7b5a7afe9b370..c61a7566388f0 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.cs @@ -1169,7 +1169,7 @@ class C { } Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Removed, o.Reason)); Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason); } @@ -1358,18 +1358,17 @@ class C { } step => Assert.True(step.Outputs.Single().Value is ClassDeclarationSyntax { Identifier.ValueText: "C" })); Assert.Collection(runResult.TrackedSteps["individualFileGlobalAliases_ForAttribute"], - s => Assert.Equal(IncrementalStepRunReason.New, s.Outputs.Single().Reason), - s => Assert.Equal(IncrementalStepRunReason.Unchanged, s.Outputs.Single().Reason)); - Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); + s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason), + s => Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason)); + Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["collectedGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["allUpGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Removed, o.Reason)); - Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); - Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); + Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); + Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason); } [Fact] @@ -1504,8 +1503,7 @@ class D { }")))); Assert.Collection(runResult.TrackedSteps["compilationUnit_ForAttribute"].Single().Outputs, o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - o => Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)); + o => Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["compilationUnitAndGlobalAliases_ForAttribute"].Single().Outputs.Single().Reason); Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps["result_ForAttribute"].Single().Outputs.Single().Reason); } diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs index f9db61cd7e355..b474ad41ba4de 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/StateTableTests.cs @@ -96,7 +96,7 @@ public void Node_Builder_Can_Add_Entries_From_Previous_Table() Assert.True(didRemoveEntries); } - private IEnumerable YieldItems(OneOrMany items) + private static IEnumerable YieldItems(OneOrMany items) { foreach (var value in items) yield return value; diff --git a/src/Compilers/Core/Portable/SourceGeneration/GlobalAliases.cs b/src/Compilers/Core/Portable/SourceGeneration/GlobalAliases.cs index d4477c455faff..a6939660c46f0 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GlobalAliases.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GlobalAliases.cs @@ -31,6 +31,22 @@ public static GlobalAliases Create(ImmutableArray<(string aliasName, string symb return aliasAndSymbolNames.IsEmpty ? Empty : new GlobalAliases(aliasAndSymbolNames); } + public static GlobalAliases Create(ImmutableArray aliasesArray) + { + if (aliasesArray.Length == 0) + return Empty; + + if (aliasesArray.Length == 1) + return aliasesArray[0]; + + var total = ArrayBuilder<(string aliasName, string symbolName)>.GetInstance(aliasesArray.Sum(a => a.AliasAndSymbolNames.Length)); + + foreach (var array in aliasesArray) + total.AddRange(array.AliasAndSymbolNames); + + return Create(total.ToImmutableAndFree()); + } + public static GlobalAliases Concat(GlobalAliases ga1, GlobalAliases ga2) { if (ga1.AliasAndSymbolNames.Length == 0) diff --git a/src/Compilers/Core/Portable/SourceGeneration/Nodes/NodeStateTable.cs b/src/Compilers/Core/Portable/SourceGeneration/Nodes/NodeStateTable.cs index d11078eaab922..c5c2aef5546fe 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/Nodes/NodeStateTable.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/Nodes/NodeStateTable.cs @@ -629,18 +629,19 @@ public TableEntry ToImmutableAndFree() Debug.Assert(_items.Count == _requestedCapacity); Debug.Assert(_states == null || _states.Count == _requestedCapacity); - var states = _states?.ToImmutableAndFree() ?? GetSingleArray(_currentState.Value); - + OneOrMany items; if (_items.Count == 1) { var item = _items[0]; _items.Free(); - return new TableEntry(OneOrMany.Create(item), states); + items = OneOrMany.Create(item); } else { - return new TableEntry(OneOrMany.Create(_items.ToImmutableAndFree()), states); + items = OneOrMany.Create(_items.ToImmutableAndFree()); } + + return new TableEntry(items, _states?.ToImmutableAndFree() ?? GetSingleArray(_currentState.Value)); } } } diff --git a/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs b/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs index 167c91c7d26a4..921fbcb704aa1 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs @@ -7,6 +7,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Transactions; @@ -20,7 +21,24 @@ namespace Microsoft.CodeAnalysis; public partial struct SyntaxValueProvider { - private static readonly ObjectPool> s_stackPool = new(static () => new()); + /// + /// Information computed about a particular tree. Cached so we don't repeatedly recompute this important + /// information each time the incremental pipeline is rerun. + /// + private record SyntaxTreeInfo(SyntaxTree Tree, bool ContainsGlobalAliases, bool ContainsAttributeList); + + /// + /// Caching of syntax-tree to the info we've computed about it. Used because compilations will have thousands of + /// trees, and the incremental pipeline will get called back for *all* of them each time a compilation changes. We + /// do not want to continually recompute this data over and over again each time that happens given that normally + /// only one tree will be different. We also do not want to create an IncrementalValuesProvider that yield this + /// information as that will mean we have a node in the tree that scales with the number of *all syntax trees*, not + /// the number of *relevant syntax trees*. This can lead to huge memory churn keeping track of a high number of + /// trees, most of which are not going to be relevant. + /// + private static readonly ConditionalWeakTable s_treeToInfo = new ConditionalWeakTable(); + + private static readonly ObjectPool> s_stackPool = new ObjectPool>(static () => new Stack()); /// /// Returns all syntax nodes of that match if that node has an attribute on it that @@ -54,17 +72,15 @@ public partial struct SyntaxValueProvider // changed. CreateSyntaxProvider will have to rerun all incremental nodes since it passes along the // SemanticModel, and that model is updated whenever any tree changes (since it is tied to the compilation). var syntaxTreesProvider = _context.CompilationProvider - .SelectMany(static (c, _) => c.SyntaxTrees) + .SelectMany((compilation, cancellationToken) => compilation.SyntaxTrees + .Select(tree => GetTreeInfo(tree, syntaxHelper, cancellationToken)) + .Where(info => info.ContainsGlobalAliases || info.ContainsAttributeList)) .WithTrackingName("compilationUnit_ForAttribute"); // Create a provider that provides (and updates) the global aliases for any particular file when it is edited. var individualFileGlobalAliasesProvider = syntaxTreesProvider - .Where((tree, cancellationToken) => - { - var root = tree.GetRoot(cancellationToken); - return syntaxHelper.ContainsGlobalAliases(root); - }) - .Select((tree, cancellationToken) => getGlobalAliasesInCompilationUnit(syntaxHelper, tree.GetRoot(cancellationToken))) + .Where((info, _) => info.ContainsGlobalAliases) + .Select((info, cancellationToken) => getGlobalAliasesInCompilationUnit(syntaxHelper, info.Tree.GetRoot(cancellationToken))) .WithTrackingName("individualFileGlobalAliases_ForAttribute"); // Create an aggregated view of all global aliases across all files. This should only update when an individual @@ -75,7 +91,7 @@ public partial struct SyntaxValueProvider .WithTrackingName("collectedGlobalAliases_ForAttribute"); var allUpGlobalAliasesProvider = collectedGlobalAliasesProvider - .Select(static (arrays, _) => GlobalAliases.Create(arrays.SelectMany(a => a.AliasAndSymbolNames).ToImmutableArray())) + .Select(static (arrays, _) => GlobalAliases.Create(arrays)) .WithTrackingName("allUpGlobalAliases_ForAttribute"); // Regenerate our data if the compilation options changed. VB can supply global aliases with compilation options, @@ -96,19 +112,12 @@ public partial struct SyntaxValueProvider // Combine the two providers so that we reanalyze every file if the global aliases change, or we reanalyze a // particular file when it's compilation unit changes. var syntaxTreeAndGlobalAliasesProvider = syntaxTreesProvider - .Where((tree, cancellationToken) => - { - // Walk the green node tree first to avoid allocating the entire red tree for files that have no attributes. - // - // Don't bother looking in trees that don't even have attributes in them. - var root = tree.GetRoot(cancellationToken); - return ContainsAttributeList(root.Green, syntaxHelper.AttributeListKind); - }) + .Where((info, _) => info.ContainsAttributeList) .Combine(allUpGlobalAliasesProvider) .WithTrackingName("compilationUnitAndGlobalAliases_ForAttribute"); - return syntaxTreeAndGlobalAliasesProvider.Select( - (tuple, c) => (tuple.Left, GetMatchingNodes(syntaxHelper, tuple.Right, tuple.Left, simpleName, predicate, c))) + return syntaxTreeAndGlobalAliasesProvider + .Select((tuple, c) => (tuple.Left.Tree, GetMatchingNodes(syntaxHelper, tuple.Right, tuple.Left.Tree, simpleName, predicate, c))) .Where(tuple => tuple.Item2.Length > 0) .WithTrackingName("result_ForAttributeInternal"); @@ -125,6 +134,25 @@ static GlobalAliases getGlobalAliasesInCompilationUnit( } } + private static SyntaxTreeInfo GetTreeInfo( + SyntaxTree tree, ISyntaxHelper syntaxHelper, CancellationToken cancellationToken) + { + // prevent captures for the case where the item is in the tree. + return s_treeToInfo.TryGetValue(tree, out var info) + ? info + : computeTreeInfo(); + + SyntaxTreeInfo computeTreeInfo() + { + var root = tree.GetRoot(cancellationToken); + var containsGlobalAliases = syntaxHelper.ContainsGlobalAliases(root); + var containsAttributeList = ContainsAttributeList(root.Green, syntaxHelper.AttributeListKind); + + var info = new SyntaxTreeInfo(tree, containsGlobalAliases, containsAttributeList); + return s_treeToInfo.GetValue(tree, _ => info); + } + } + private static ImmutableArray GetMatchingNodes( ISyntaxHelper syntaxHelper, GlobalAliases globalAliases, @@ -306,10 +334,12 @@ private static bool ContainsAttributeList(GreenNode node, int attributeListKind) if (node.RawKind == attributeListKind) return true; - foreach (var child in node.ChildNodesAndTokens()) + for (int i = 0, n = node.SlotCount; i < n; i++) { - if (node.IsToken) - return false; + var child = node.GetSlot(i); + + if (child is null || child.IsToken) + continue; if (ContainsAttributeList(child, attributeListKind)) return true; diff --git a/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.vb b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.vb index 2e45d93da0a52..89d00c4a1f098 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_FullyQualifiedName.vb @@ -1008,8 +1008,7 @@ end class Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, - Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)) + Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("result_ForAttributeInternal").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps("compilationAndGroupedNodes_ForAttributeWithMetadataName").Single().Outputs.Single().Reason) @@ -1055,8 +1054,7 @@ end class Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, - Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)) + Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("result_ForAttributeInternal").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps("compilationAndGroupedNodes_ForAttributeWithMetadataName").Single().Outputs.Single().Reason) @@ -1106,8 +1104,7 @@ end class")))) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, - Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)) + Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("result_ForAttributeInternal").Single().Outputs, Sub(t) Assert.Equal(IncrementalStepRunReason.Cached, t.Reason)) @@ -1160,8 +1157,7 @@ Sub(_step) Assert.Collection(_step.Outputs, Sub(t) Assert.True(IsClassStatementW Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, Sub(s) Assert.Equal(IncrementalStepRunReason.Unchanged, s.Reason), - Sub(s) Assert.Equal(IncrementalStepRunReason.Unchanged, s.Reason), - Sub(s) Assert.Equal(IncrementalStepRunReason.Modified, s.Reason)) + Sub(s) Assert.Equal(IncrementalStepRunReason.Unchanged, s.Reason)) Assert.Collection(runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute"), Sub(s) Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason), Sub(s) Assert.Equal(IncrementalStepRunReason.Cached, s.Outputs.Single().Reason)) @@ -1275,8 +1271,7 @@ end class Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, - Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason), - Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)) + Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)) Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps("result_ForAttributeInternal").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.New, runResult.TrackedSteps("compilationAndGroupedNodes_ForAttributeWithMetadataName").Single().Outputs.Single().Reason) diff --git a/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.vb b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.vb index 627091e179321..d89ef1d11a824 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests_Attributes_SimpleName.vb @@ -1216,7 +1216,7 @@ end class Assert.Equal(IncrementalStepRunReason.Unchanged, runResult.TrackedSteps("collectedGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) - Assert.Equal(IncrementalStepRunReason.Modified, runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs.Single().Reason) + Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Removed, runResult.TrackedSteps("result_ForAttribute").Single().Outputs.Single().Reason) End Sub @@ -1421,8 +1421,7 @@ end class")))) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("allUpGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Collection(runResult.TrackedSteps("compilationUnit_ForAttribute").Single().Outputs, - Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason), - Sub(o) Assert.Equal(IncrementalStepRunReason.Modified, o.Reason)) + Sub(o) Assert.Equal(IncrementalStepRunReason.Unchanged, o.Reason)) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("compilationUnitAndGlobalAliases_ForAttribute").Single().Outputs.Single().Reason) Assert.Equal(IncrementalStepRunReason.Cached, runResult.TrackedSteps("result_ForAttribute").Single().Outputs.Single().Reason) End Sub diff --git a/src/Tools/IdeCoreBenchmarks/IncrementalSourceGeneratorBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/IncrementalSourceGeneratorBenchmarks.cs index d57d35a9d1a53..3626836aefdf7 100644 --- a/src/Tools/IdeCoreBenchmarks/IncrementalSourceGeneratorBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/IncrementalSourceGeneratorBenchmarks.cs @@ -173,16 +173,18 @@ public async Task RunGenerator() Thread.Sleep(5000); var totalIncrementalTime = TimeSpan.Zero; - for (var i = 0; i < 5000; i++) + for (var i = 0; i < 50000; i++) { - var changedText = sourceText.WithChanges(new TextChange(new TextSpan(0, 0), $"// added text{i}\r\n")); + var changedText = sourceText.WithChanges(new TextChange(sourceText.Lines[0].Span, $"// added text{i}")); var changedTree = syntaxTree.WithChangedText(changedText); - var changedCompilation = compilation.ReplaceSyntaxTree(syntaxTree, changedTree); + compilation = compilation.ReplaceSyntaxTree(syntaxTree, changedTree); + sourceText = changedText; + syntaxTree = changedTree; start = DateTime.Now; - driver = driver.RunGenerators(changedCompilation); + driver = driver.RunGenerators(compilation); var incrementalTime = DateTime.Now - start; - if (i % 100 == 0) + if (i % 5000 == 0) Console.WriteLine("Incremental time: " + incrementalTime); totalIncrementalTime += incrementalTime; }