Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve DocumentBasedFixAllProvider performance for multiple documents #1983

Merged
merged 12 commits into from
Dec 28, 2015

Conversation

sharwell
Copy link
Member

Previously, custom fix all providers called FixAllContext.GetDocumentDiagnosticsAsync for every document in the fix all scope. This change first replaces those calls with a single call to FixAllContextHelpers.GetDocumentDiagnosticsToFixAsync, which was extracted from CustomBatchFixAllProvider. It goes on to instead operate on a CompilationWithAnalyzers following the commentary in #1979. The result is improved performance when fixing violations in large projects, especially when only a few documents in the project contained violations.

Fixes #1974.

@sharwell sharwell added this to the 1.0.0 RC 3 milestone Dec 22, 2015
@codecov-io
Copy link

Current coverage is 93.24%

Merging #1983 into stabilization will increase coverage by +13.90% as of 6f7d1c8

@@            stabilization   #1983   diff @@
=============================================
  Files                 559     561      +2
  Stmts               35166   35322    +156
  Branches             9747    2266   -7481
  Methods                                  
=============================================
+ Hit                 27903   32937   +5034
+ Partial              5702     751   -4951
- Missed               1561    1634     +73

Review entire Coverage Diff as of 6f7d1c8

Powered by Codecov. Updated on successful CI builds.

Previously, custom fix all providers called FixAllContext.GetDocumentDiagnosticsAsync
for every document in the fix all scope. This change replaces those calls
with a single call to FixAllContextHelpers.GetDocumentDiagnosticsToFixAsync,
which was extracted from CustomBatchFixAllProvider. The result is improved
performance when fixing violations in large projects, especially when only
a few documents in the project contained violations.
Also updated FixAllContextHelper to support code fixes for standard C#
compiler warnings.
@sharwell sharwell self-assigned this Dec 23, 2015
if (analyzers.Any())
{
var compilationWithAnalyzers = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, fixAllContext.CancellationToken);
diagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mavasani I'm finding that when I use CompilationWithAnalyzers here along with #1979, even though all diagnostics are reported in the errors pane in Visual Studio not all diagnostics end up corrected by the Fix All in Project and Fix All in Solution operations. Is there some way I can update this method so we have the performance of CompilationWithAnalyzers.GetAnalyzerDiagnosticsAsync, but also get all diagnostics?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetAnalyzerDiagnostics seems to be affected by the same bug you pointed out in your churn testing. You may try to replicate what IDE diagnostic service does sequentially - for each document invoke GetAnalyzerSyntaxDiagnosticsAsync and GetAnalyzerSemanticDiagnosticsAsync. If you also have any compilation end analyzers, then also invoke GetAnalyzerCompilationDiagnosticsAsync at the end. This won't be as fast as GetAnalyzerDiagnosticsAsync() but should be faster then current performance of FixAllContext.GetAllDiagnosticsAsync.

This commit also moves back to using FixAllContext.GetAllDiagnosticsAsync
for non-1.1 versions of Roslyn, where performance of the operation wasn't
causing a major problem.
@sharwell
Copy link
Member Author

With the latest change, the churn tests indicate that aside from true duplicates in 1.0.0, all three tested versions of Roslyn produce identical outputs.


// Note that the following loop to obtain syntax and semantic diagnostics for each document cannot operate
// on parallel due to our use of a single CompilationWithAnalyzers instance.
var diagnostics = ImmutableArray<Diagnostic>.Empty;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 using an ImmutableArray<Diagnostic>.Builder or a List<Diagnostic> would improve the performance when adding diagnostics. There is no need to have the diagnostics in the ImmutableArray<Diagnostic> type yet, as they are never passed to another method.

@vweijsters
Copy link
Contributor

👍 Looks good to me, with two small remarks.

@pdelvo
Copy link
Member

pdelvo commented Dec 27, 2015

👍

sharwell added a commit that referenced this pull request Dec 28, 2015
Improve DocumentBasedFixAllProvider performance for multiple documents
@sharwell sharwell merged commit 1c701f5 into DotNetAnalyzers:stabilization Dec 28, 2015
@sharwell sharwell deleted the fixall-performance branch December 28, 2015 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants