@@ -11,6 +11,7 @@ namespace StyleCopTester
1111 using System . Linq ;
1212 using System . Reflection ;
1313 using System . Text ;
14+ using System . Text . RegularExpressions ;
1415 using System . Threading ;
1516 using System . Threading . Tasks ;
1617 using System . Windows . Threading ;
@@ -124,9 +125,24 @@ private static async Task MainAsync(string[] args, CancellationToken cancellatio
124125
125126 Console . WriteLine ( $ "Found { allDiagnostics . Length } diagnostics in { stopwatch . ElapsedMilliseconds } ms") ;
126127
127- bool testDocuments = args . Contains ( "/editperf" ) ;
128+ bool testDocuments = args . Contains ( "/editperf" ) || args . Any ( arg => arg . StartsWith ( "/editperf:" ) ) ;
128129 if ( testDocuments )
129130 {
131+ Func < string , bool > documentMatch = _ => true ;
132+ string matchArg = args . FirstOrDefault ( arg => arg . StartsWith ( "/editperf:" ) ) ;
133+ if ( matchArg != null )
134+ {
135+ Regex expression = new Regex ( matchArg . Substring ( "/editperf:" . Length ) , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
136+ documentMatch = documentPath => expression . IsMatch ( documentPath ) ;
137+ }
138+
139+ int iterations = 10 ;
140+ string iterationsArg = args . FirstOrDefault ( arg => arg . StartsWith ( "/edititer:" ) ) ;
141+ if ( iterationsArg != null )
142+ {
143+ iterations = int . Parse ( iterationsArg . Substring ( "/edititer:" . Length ) ) ;
144+ }
145+
130146 var projectPerformance = new Dictionary < ProjectId , double > ( ) ;
131147 var documentPerformance = new Dictionary < DocumentId , DocumentAnalyzerPerformance > ( ) ;
132148 foreach ( var projectId in solution . ProjectIds )
@@ -140,20 +156,21 @@ private static async Task MainAsync(string[] args, CancellationToken cancellatio
140156 foreach ( var documentId in project . DocumentIds )
141157 {
142158 var document = project . GetDocument ( documentId ) ;
143- var currentDocumentPerformance = await TestDocumentPerformanceAsync ( analyzers , project , documentId , force , cancellationToken ) . ConfigureAwait ( false ) ;
159+ if ( ! documentMatch ( document . FilePath ) )
160+ {
161+ continue ;
162+ }
163+
164+ var currentDocumentPerformance = await TestDocumentPerformanceAsync ( analyzers , project , documentId , iterations , force , cancellationToken ) . ConfigureAwait ( false ) ;
144165 Console . WriteLine ( $ "{ document . FilePath ?? document . Name } : { currentDocumentPerformance . EditsPerSecond : 0.00} ") ;
145166 documentPerformance . Add ( documentId , currentDocumentPerformance ) ;
146167 }
147168
148- double sumOfDocumentAverages = 0 ;
149- foreach ( var documentId in project . DocumentIds )
150- {
151- sumOfDocumentAverages += documentPerformance [ documentId ] . EditsPerSecond ;
152- }
153-
154- if ( sumOfDocumentAverages != 0 )
169+ double sumOfDocumentAverages = documentPerformance . Where ( x => x . Key . ProjectId == projectId ) . Sum ( x => x . Value . EditsPerSecond ) ;
170+ double documentCount = documentPerformance . Where ( x => x . Key . ProjectId == projectId ) . Count ( ) ;
171+ if ( documentCount > 0 )
155172 {
156- projectPerformance [ project . Id ] = sumOfDocumentAverages / project . DocumentIds . Count ;
173+ projectPerformance [ project . Id ] = sumOfDocumentAverages / documentCount ;
157174 }
158175 }
159176
@@ -215,7 +232,7 @@ private static async Task MainAsync(string[] args, CancellationToken cancellatio
215232 }
216233 }
217234
218- private static async Task < DocumentAnalyzerPerformance > TestDocumentPerformanceAsync ( ImmutableArray < DiagnosticAnalyzer > analyzers , Project project , DocumentId documentId , bool force , CancellationToken cancellationToken )
235+ private static async Task < DocumentAnalyzerPerformance > TestDocumentPerformanceAsync ( ImmutableArray < DiagnosticAnalyzer > analyzers , Project project , DocumentId documentId , int iterations , bool force , CancellationToken cancellationToken )
219236 {
220237 var supportedDiagnosticsSpecificOptions = new Dictionary < string , ReportDiagnostic > ( ) ;
221238 if ( force )
@@ -238,7 +255,6 @@ private static async Task<DocumentAnalyzerPerformance> TestDocumentPerformanceAs
238255 var modifiedCompilationOptions = project . CompilationOptions . WithSpecificDiagnosticOptions ( modifiedSpecificDiagnosticOptions ) ;
239256
240257 var stopwatch = Stopwatch . StartNew ( ) ;
241- const int iterations = 10 ;
242258 for ( int i = 0 ; i < iterations ; i ++ )
243259 {
244260 var processedProject = project . WithCompilationOptions ( modifiedCompilationOptions ) ;
@@ -594,6 +610,8 @@ private static void PrintHelp()
594610 Console . WriteLine ( "/id:<id> Enable analyzer with diagnostic ID < id > (when this is specified, only this analyzer is enabled)" ) ;
595611 Console . WriteLine ( "/apply Write code fix changes back to disk" ) ;
596612 Console . WriteLine ( "/force Force an analyzer to be enabled, regardless of the configured rule set(s) for the solution" ) ;
613+ Console . WriteLine ( "/editperf[:<match>] Test the incremental performance of analyzers to simulate the behavior of editing files. If <match> is specified, only files matching this regular expression are evaluated for editor performance." ) ;
614+ Console . WriteLine ( "/edititer:<iterations> Specifies the number of iterations to use for testing documents with /editperf. When this is not specified, the default value is 10." ) ;
597615 }
598616
599617 private struct DocumentAnalyzerPerformance
0 commit comments