DotNetAnalyzers / StyleCopAnalyzers

An implementation of StyleCop rules using the .NET Compiler Platform
MIT License
2.66k stars 507 forks source link

Investigating analyzer impact on build times #2975

Open peteroupc opened 5 years ago

peteroupc commented 5 years ago

StyleCop Classic used to write information about files it analyzed, including analysis results, in an XML cache called StyleCop.Cache, to speed the time it takes to analyze a project if some of the source code files are unchanged in the meantime. Although StyleCop Analyzers also has caches, they are limited to storing using aliases and copyright texts, but nothing like a results cache like StyleCop Classic used to have.

In my experience, running the StyleCop analyzer takes a considerable part of a project's build time even if it ultimately finds few or no violations, and I feel that having a results cache (like StyleCop.Cache) will speed up this time because StyleCop would then focus analysis on only those files that have changed, which is often not many files.

sharwell commented 5 years ago

@peteroupc StyleCop Analyzers is not StyleCop Classic. If you find an indication of a performance problem, please file an issue and we will work to resolve it directly.

peteroupc commented 5 years ago

I can't speak of the slow performance of StyleCop Analyzers except in general terms. I know that StyleCop Analyzers is more than doubling build time of my projects but I don't know where to start in finding a specific "performance problem" of the kind you have in mind.

sharwell commented 5 years ago

What was the build time prior to StyleCop Analyzers, and the build time after?

Do you have any other analyzers installed in your project?

peteroupc commented 5 years ago

For one project of mine, the build time (msbuild /t:rebuild) was—

resulting in almost triple the build time. This project used no other analyzers than StyleCop Analyzers.

sharwell commented 5 years ago

@peteroupc The last time I measured it, the performance cost of StyleCop Analyzers was about 90% in the analyzer driver (enabled whenever any analyzer is installed and enabled) and about 10% StyleCop Analyzers itself. This project only has control over the performance of the latter. The easiest way to see if this is impacting you is to install another analyzer, e.g. FXCop Analyzers, and then re-run your comparison between StyleCop Analyzers installed or not. In this scenario, I would expect the difference between the two cases to be much less than 1:48.

The other thing that can impact performance is the number of diagnostics reported by the analyzers. This is the same as the number of diagnostics you see if the project has no suppressions. StyleCop Analyzers is optimized for cases where no diagnostics are reported. A few diagnostics wouldn't make much difference, but if are seeing and/or suppressing thousands of diagnostics, it would have a noticeable impact.

peteroupc commented 5 years ago

The build time for the same project is—

Also, several rules were disabled in the project in question; enabling them raised the build time to about 4:01 (with just StyleCop Analyzers) and added almost 5000 additional warnings (mostly SA1500 and SA1513); though this may be due to overhead from displaying those warnings.

sharwell commented 5 years ago

Can you try adding /p:ReportAnalyzer=true to your MSBuild command line to see execution times by analyzer?

sharwell commented 5 years ago

@peteroupc If the results from ReportAnalyzer don't show in your output, you can add /bl:Build.binlog to your MSBuild command line as well. This will create an output file Build.binlog that you can open with the MSBuild Structured Log Viewer. This output format contains the information you would normally see with diagnostic level output, but is much faster than /v:d and the log viewer contains search functionality.

When you open the log in the viewer, you'll want to search for the following:

"Total analyzer execution time"

Then you can click on a line on the left pane to get details.

image

sharwell commented 5 years ago

@peteroupc I reopened this as a question so we can work through the issue and find the root cause

peteroupc commented 5 years ago

I got useful information from adding /v:detailed to the command line. Notably, the output shows that the analysis spends about 22% on a single rule: SA1604, "element documentation must have summary". Presumably this has to do with the fact that I include most of my project's XML documentation (including summaries) in a separate XML file and the analyzer may be loading and reloading that XML file each time it checks the XML documentation. Another reason may be the XPath overhead of resolving XML paths.

The following checks consumed a noticeable part of the analysis time, but to a much lesser extent (at most 3% each):

SA1009, SA1027, SA1137, SA1008, SA1120, SA1101, SA1000

Note that the above is from a project with StyleCop.Analyzers and FxCop Analyzers, and the latter's checks take considerably less time.

sharwell commented 5 years ago

I may be able to improve performance of that scenario. I'll take a look, and if I can get a private build up on AppVeyor I'll show you how to reference it for testing.

sharwell commented 5 years ago

I'm not sure I'll be able to address the SA1604 issue in short order. I would suggest disabling it for now.

Is there a reason you use <include> so much? I'm wondering if a better experience would be had by inlining the documentation to the comments.

peteroupc commented 5 years ago

Disabling SA1604 didn't have much effect; rather it simply shifted the bulk of the analysis time to another documentation-related check, this time SA1614.

I include XML documentation in my projects because having all the documentation for a project or library in a single file is more convenient for me, for such purposes as editing.

sharwell commented 5 years ago

You may need to iterate a few times to disable all impacted rules. Both of the expensive pieces of the <include> evaluation are cached across analyzers, so it will only impact the first one that evaluates a given comment.

peteroupc commented 5 years ago

I believe the solution ultimately lies in improving the performance or caching the results of GetDocumentationCommentXml, which has an implementation that I don't know about and is beyond the reach of StyleCop Analyzers. It may be a method deep in the analysis engine. Does GetDocumentationCommentXml cache XML documents if the same document (same <include file='...'>) is included more than once in the same project? I don't know. Does it cache XPath results to avoid reevaluating the same XPath for the same XML file? I don't know.

jnm2 commented 5 years ago

Just chiming in. I'm trying to cut the inner loop (make change + run tests) time down in two particular projects. With about half the rules disabled, I found that StyleCop Analyers adds an additional 3.7 seconds (+67%) to the build time in our most common scenario. I'm prioritizing our developers' trains of thought over catching style issues before PR.

bddckr commented 5 years ago

I don't see the suite of analyzers added through this project adding unexpectedly large delays to my solutions. Since I use a lot of analyzers I do end up having the need to selectively disable live analysis or even do so during a build, though, on a machine-to-machine basis.

It looks like a recent Visual Studio update brought us settings to configure each:

(Click to read the release notes.)

Each checkbox adds a property to the .csproj and thus can be used by us manually, to speed things up as needed:

<RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
jnm2 commented 3 years ago

In one of our projects, StyleCop has grown to adding 30 seconds to each build on average:

image

Full text ``` 29.577 s StyleCop.Analyzers, Version=1.2.0.354, Culture=neutral, PublicKeyToken=cfeb5dbada5e1c25 StyleCop.Analyzers.ReadabilityRules.SA1121UseBuiltInTypeAlias (SA1121) = 7.551 s StyleCop.Analyzers.SpacingRules.SA1027UseTabsCorrectly (SA1027) = 1.347 s StyleCop.Analyzers.SpacingRules.SA1000KeywordsMustBeSpacedCorrectly (SA1000) = 1.007 s StyleCop.Analyzers.ReadabilityRules.SA1137ElementsShouldHaveTheSameIndentation (SA1137) = 952 ms StyleCop.Analyzers.SpacingRules.SA1019MemberAccessSymbolsMustBeSpacedCorrectly (SA1019) = 745 ms StyleCop.Analyzers.SpacingRules.SA1010OpeningSquareBracketsMustBeSpacedCorrectly (SA1010) = 708 ms StyleCop.Analyzers.SpacingRules.SA1028CodeMustNotContainTrailingWhitespace (SA1028) = 662 ms StyleCop.Analyzers.SpacingRules.SA1013ClosingBracesMustBeSpacedCorrectly (SA1013) = 609 ms StyleCop.Analyzers.ReadabilityRules.SA1141UseTupleSyntax (SA1141) = 582 ms StyleCop.Analyzers.DocumentationRules.FileHeaderAnalyzers (SA1633, SA1634, SA1635, SA1636, SA1637, SA1638, SA1639, SA1640, SA1641) = 575 ms StyleCop.Analyzers.DocumentationRules.SA1604ElementDocumentationMustHaveSummary (SA1604) = 574 ms StyleCop.Analyzers.SpacingRules.SA1015ClosingGenericBracketsMustBeSpacedCorrectly (SA1015) = 567 ms StyleCop.Analyzers.SpacingRules.SA1004DocumentationLinesMustBeginWithSingleSpace (SA1004) = 563 ms StyleCop.Analyzers.SpacingRules.SA1006PreprocessorKeywordsMustNotBePrecededBySpace (SA1006) = 556 ms StyleCop.Analyzers.SpacingRules.SA1001CommasMustBeSpacedCorrectly (SA1001) = 531 ms StyleCop.Analyzers.SpacingRules.SA1021NegativeSignsMustBeSpacedCorrectly (SA1021) = 514 ms StyleCop.Analyzers.LayoutRules.SA1509OpeningBracesMustNotBePrecededByBlankLine (SA1509) = 513 ms StyleCop.Analyzers.SpacingRules.SA1024ColonsMustBeSpacedCorrectly (SA1024) = 486 ms StyleCop.Analyzers.DocumentationRules.SA1606ElementDocumentationMustHaveSummaryText (SA1606) = 483 ms StyleCop.Analyzers.SpacingRules.SA1012OpeningBracesMustBeSpacedCorrectly (SA1012) = 477 ms StyleCop.Analyzers.SpacingRules.SA1020IncrementDecrementSymbolsMustBeSpacedCorrectly (SA1020) = 466 ms StyleCop.Analyzers.SpacingRules.SA1014OpeningGenericBracketsMustBeSpacedCorrectly (SA1014) = 463 ms StyleCop.Analyzers.SpacingRules.SA1007OperatorKeywordMustBeFollowedBySpace (SA1007) = 457 ms StyleCop.Analyzers.SpacingRules.SA1017ClosingAttributeBracketsMustBeSpacedCorrectly (SA1017) = 457 ms StyleCop.Analyzers.SpacingRules.SA1016OpeningAttributeBracketsMustBeSpacedCorrectly (SA1016) = 453 ms StyleCop.Analyzers.DocumentationRules.SA1625ElementDocumentationMustNotBeCopiedAndPasted (SA1625) = 451 ms StyleCop.Analyzers.SpacingRules.SA1022PositiveSignsMustBeSpacedCorrectly (SA1022) = 450 ms StyleCop.Analyzers.SpacingRules.SA1011ClosingSquareBracketsMustBeSpacedCorrectly (SA1011) = 438 ms StyleCop.Analyzers.ReadabilityRules.SA1110OpeningParenthesisMustBeOnDeclarationLine (SA1110) = 411 ms StyleCop.Analyzers.DocumentationRules.PropertySummaryDocumentationAnalyzer (SA1623, SA1624) = 362 ms StyleCop.Analyzers.DocumentationRules.SA1608ElementDocumentationMustNotHaveDefaultSummary (SA1608) = 358 ms StyleCop.Analyzers.DocumentationRules.SA1614ElementParameterDocumentationMustHaveText (SA1614) = 344 ms StyleCop.Analyzers.DocumentationRules.SA1612ElementParameterDocumentationMustMatchElementParameters (SA1612) = 295 ms StyleCop.Analyzers.DocumentationRules.SA1629DocumentationTextMustEndWithAPeriod (SA1629) = 294 ms StyleCop.Analyzers.DocumentationRules.SA1616ElementReturnValueDocumentationMustHaveText (SA1616) = 286 ms StyleCop.Analyzers.DocumentationRules.SA1613ElementParameterDocumentationMustDeclareParameterName (SA1613) = 268 ms StyleCop.Analyzers.DocumentationRules.SA1605PartialElementDocumentationMustHaveSummary (SA1605) = 264 ms StyleCop.Analyzers.OrderingRules.SA1208SystemUsingDirectivesMustBePlacedBeforeOtherUsingDirectives (SA1208) = 245 ms StyleCop.Analyzers.OrderingRules.SA1209UsingAliasDirectivesMustBePlacedAfterOtherUsingDirectives (SA1209) = 215 ms StyleCop.Analyzers.OrderingRules.SA1217UsingStaticDirectivesMustBeOrderedAlphabetically (SA1217) = 170 ms StyleCop.Analyzers.NamingRules.SA1316TupleElementNamesShouldUseCorrectCasing (SA1316) = 155 ms StyleCop.Analyzers.OrderingRules.SA1210UsingDirectivesMustBeOrderedAlphabeticallyByNamespace (SA1210) = 134 ms StyleCop.Analyzers.ReadabilityRules.SA1112ClosingParenthesisMustBeOnLineOfOpeningParenthesis (SA1112) = 134 ms StyleCop.Analyzers.LayoutRules.SA1505OpeningBracesMustNotBeFollowedByBlankLine (SA1505) = 129 ms StyleCop.Analyzers.DocumentationRules.SA1607PartialElementDocumentationMustHaveSummaryText (SA1607) = 124 ms StyleCop.Analyzers.ReadabilityRules.SA1142ReferToTupleElementsByName (SA1142) = 115 ms StyleCop.Analyzers.ReadabilityRules.SA1117ParametersMustBeOnSameLineOrSeparateLines (SA1117) = 110 ms StyleCop.Analyzers.ReadabilityRules.SA1135UsingDirectivesMustBeQualified (SA1135) = 107 ms StyleCop.Analyzers.ReadabilityRules.SA1113CommaMustBeOnSameLineAsPreviousParameter (SA1113) = 106 ms StyleCop.Analyzers.ReadabilityRules.SA1129DoNotUseDefaultValueTypeConstructor (SA1129) = 99 ms StyleCop.Analyzers.NamingRules.SA1313ParameterNamesMustBeginWithLowerCaseLetter (SA1313) = 86 ms StyleCop.Analyzers.LayoutRules.SA1508ClosingBracesMustNotBePrecededByBlankLine (SA1508) = 75 ms StyleCop.Analyzers.DocumentationRules.SA1610PropertyDocumentationMustHaveValueText (SA1610) = 69 ms StyleCop.Analyzers.SpecialRules.SA0002InvalidSettingsFile (SA0002) = 66 ms StyleCop.Analyzers.MaintainabilityRules.SA1413UseTrailingCommasInMultiLineInitializers (SA1413) = 64 ms StyleCop.Analyzers.DocumentationRules.SA1648InheritDocMustBeUsedWithInheritingClass (SA1648) = 54 ms StyleCop.Analyzers.MaintainabilityRules.SA1404CodeAnalysisSuppressionMustHaveJustification (SA1404) = 48 ms StyleCop.Analyzers.OrderingRules.SA1207ProtectedMustComeBeforeInternal (SA1207) = 43 ms StyleCop.Analyzers.LayoutRules.SA1518UseLineEndingsCorrectlyAtEndOfFile (SA1518) = 38 ms StyleCop.Analyzers.MaintainabilityRules.SA1400AccessModifierMustBeDeclared (SA1400) = 37 ms StyleCop.Analyzers.DocumentationRules.GenericTypeParameterDocumentationAnalyzer (SA1620, SA1621, SA1622) = 36 ms StyleCop.Analyzers.MaintainabilityRules.SA1403FileMayOnlyContainASingleNamespace (SA1403) = 32 ms StyleCop.Analyzers.MaintainabilityRules.SA1405DebugAssertMustProvideMessageText (SA1405) = 32 ms StyleCop.Analyzers.MaintainabilityRules.SA1414TupleTypesInSignaturesShouldHaveElementNames (SA1414) = 28 ms StyleCop.Analyzers.LayoutRules.SA1506ElementDocumentationHeadersMustNotBeFollowedByBlankLine (SA1506) = 26 ms StyleCop.Analyzers.NamingRules.SA1304NonPrivateReadonlyFieldsMustBeginWithUpperCaseLetter (SA1304) = 24 ms StyleCop.Analyzers.NamingRules.SA1312VariableNamesMustBeginWithLowerCaseLetter (SA1312) = 23 ms StyleCop.Analyzers.SpacingRules.SA1018NullableTypeSymbolsMustNotBePrecededBySpace (SA1018) = 20 ms StyleCop.Analyzers.ReadabilityRules.SA1125UseShorthandForNullableTypes (SA1125) = 19 ms StyleCop.Analyzers.ReadabilityRules.SA110xQueryClauses (SA1102, SA1103, SA1104, SA1105) = 18 ms StyleCop.Analyzers.DocumentationRules.SA1617VoidReturnValueMustNotBeDocumented (SA1617) = 16 ms StyleCop.Analyzers.NamingRules.SA1311StaticReadonlyFieldsMustBeginWithUpperCaseLetter (SA1311) = 15 ms StyleCop.Analyzers.LayoutRules.SA1520UseBracesConsistently (SA1520) = 13 ms StyleCop.Analyzers.NamingRules.SA1309FieldNamesMustNotBeginWithUnderscore (SA1309) = 13 ms StyleCop.Analyzers.NamingRules.SA1307AccessibleFieldsMustBeginWithUpperCaseLetter (SA1307) = 12 ms StyleCop.Analyzers.NamingRules.SA1308VariableNamesMustNotBePrefixed (SA1308) = 12 ms StyleCop.Analyzers.MaintainabilityRules.SA1406DebugFailMustProvideMessageText (SA1406) = 11 ms StyleCop.Analyzers.OrderingRules.SA1211UsingAliasDirectivesMustBeOrderedAlphabeticallyByAliasName (SA1211) = 10 ms StyleCop.Analyzers.ReadabilityRules.SA1106CodeMustNotContainEmptyStatements (SA1106) = 10 ms StyleCop.Analyzers.NamingRules.SA1303ConstFieldNamesMustBeginWithUpperCaseLetter (SA1303) = 9 ms StyleCop.Analyzers.OrderingRules.SA1216UsingStaticDirectivesMustBePlacedAtTheCorrectLocation (SA1216) = 9 ms StyleCop.Analyzers.LayoutRules.SA1504AllAccessorsMustBeSingleLineOrMultiLine (SA1504) = 8 ms StyleCop.Analyzers.LayoutRules.SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine (SA1510) = 8 ms StyleCop.Analyzers.MaintainabilityRules.SA1119StatementMustNotUseUnnecessaryParenthesis (SA1119, SA1119_p) = 8 ms StyleCop.Analyzers.LayoutRules.SA1517CodeMustNotContainBlankLinesAtStartOfFile (SA1517) = 7 ms StyleCop.Analyzers.OrderingRules.SA1212PropertyAccessorsMustFollowOrder (SA1212) = 7 ms StyleCop.Analyzers.DocumentationRules.SA1627DocumentationTextMustNotBeEmpty (SA1627) = 6 ms StyleCop.Analyzers.MaintainabilityRules.SA1407ArithmeticExpressionsMustDeclarePrecedence (SA1407) = 6 ms StyleCop.Analyzers.DocumentationRules.SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes (SA1626) = 5 ms StyleCop.Analyzers.MaintainabilityRules.SA1408ConditionalExpressionsMustDeclarePrecedence (SA1408) = 5 ms StyleCop.Analyzers.SpacingRules.SA1026CodeMustNotContainSpaceAfterNewKeywordInImplicitlyTypedArrayAllocation (SA1026) = 5 ms StyleCop.Analyzers.DocumentationRules.SA1651DoNotUsePlaceholderElements (SA1651) = 4 ms StyleCop.Analyzers.LayoutRules.SA1501StatementMustNotBeOnASingleLine (SA1501) = 4 ms StyleCop.Analyzers.LayoutRules.SA1503BracesMustNotBeOmitted (SA1503) = 4 ms StyleCop.Analyzers.NamingRules.SA1302InterfaceNamesMustBeginWithI (SA1302) = 3 ms StyleCop.Analyzers.NamingRules.SA1314TypeParameterNamesMustBeginWithT (SA1314) = 2 ms StyleCop.Analyzers.OrderingRules.SA1213EventAccessorsMustFollowOrder (SA1213) = 2 ms StyleCop.Analyzers.ReadabilityRules.SA1123DoNotPlaceRegionsWithinElements (SA1123) = 2 ms StyleCop.Analyzers.ReadabilityRules.SA1136EnumValuesShouldBeOnSeparateLines (SA1136) = 2 ms StyleCop.Analyzers.SpecialRules.SA0001XmlCommentAnalysisDisabled (SA0001) = 2 ms StyleCop.Analyzers.DocumentationRules.SA1600ElementsMustBeDocumented (SA1600) = 1 ms StyleCop.Analyzers.MaintainabilityRules.SA1411AttributeConstructorMustNotUseUnnecessaryParenthesis (SA1411) = 1 ms StyleCop.Analyzers.NamingRules.SA1300ElementMustBeginWithUpperCaseLetter (SA1300) = 1 ms StyleCop.Analyzers.OrderingRules.SA1204StaticElementsMustAppearBeforeInstanceElements (SA1204) = 1 ms StyleCop.Analyzers.DocumentationRules.SA1601PartialElementsMustBeDocumented (SA1601) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1602EnumerationItemsMustBeDocumented (SA1602) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1603DocumentationMustContainValidXml (SA1603) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1609PropertyDocumentationMustHaveValue (SA1609) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1611ElementParametersMustBeDocumented (SA1611) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1615ElementReturnValueMustBeDocumented (SA1615) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1618GenericTypeParametersMustBeDocumented (SA1618) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1619GenericTypeParametersMustBeDocumentedPartialClass (SA1619) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1628DocumentationTextMustBeginWithACapitalLetter (SA1628) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1630DocumentationTextMustContainWhitespace (SA1630) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1631DocumentationMustMeetCharacterPercentage (SA1631) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1632DocumentationTextMustMeetMinimumCharacterLength (SA1632) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1642ConstructorSummaryDocumentationMustBeginWithStandardText (SA1642) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1643DestructorSummaryDocumentationMustBeginWithStandardText (SA1643) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1644DocumentationHeadersMustNotContainBlankLines (SA1644) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1645IncludedDocumentationFileDoesNotExist (SA1645) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1646IncludedDocumentationXPathDoesNotExist (SA1646) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1647IncludeNodeDoesNotContainValidFileAndPath (SA1647) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1649FileNameMustMatchTypeName (SA1649) = 0 ms StyleCop.Analyzers.DocumentationRules.SA1650ElementDocumentationMustBeSpelledCorrectly (SA1650) = 0 ms StyleCop.Analyzers.LayoutRules.SA1500BracesForMultiLineStatementsMustNotShareLine (SA1500) = 0 ms StyleCop.Analyzers.LayoutRules.SA1502ElementMustNotBeOnASingleLine (SA1502) = 0 ms StyleCop.Analyzers.LayoutRules.SA1507CodeMustNotContainMultipleBlankLinesInARow (SA1507) = 0 ms StyleCop.Analyzers.LayoutRules.SA1511WhileDoFooterMustNotBePrecededByBlankLine (SA1511) = 0 ms StyleCop.Analyzers.LayoutRules.SA1512SingleLineCommentsMustNotBeFollowedByBlankLine (SA1512) = 0 ms StyleCop.Analyzers.LayoutRules.SA1513ClosingBraceMustBeFollowedByBlankLine (SA1513) = 0 ms StyleCop.Analyzers.LayoutRules.SA1514ElementDocumentationHeaderMustBePrecededByBlankLine (SA1514) = 0 ms StyleCop.Analyzers.LayoutRules.SA1515SingleLineCommentMustBePrecededByBlankLine (SA1515) = 0 ms StyleCop.Analyzers.LayoutRules.SA1516ElementsMustBeSeparatedByBlankLine (SA1516) = 0 ms StyleCop.Analyzers.LayoutRules.SA1519BracesMustNotBeOmittedFromMultiLineChildStatement (SA1519) = 0 ms StyleCop.Analyzers.MaintainabilityRules.SA1401FieldsMustBePrivate (SA1401) = 0 ms StyleCop.Analyzers.MaintainabilityRules.SA1402FileMayOnlyContainASingleType (SA1402) = 0 ms StyleCop.Analyzers.MaintainabilityRules.SA1409RemoveUnnecessaryCode (SA1409) = 0 ms StyleCop.Analyzers.MaintainabilityRules.SA1410RemoveDelegateParenthesisWhenPossible (SA1410) = 0 ms StyleCop.Analyzers.MaintainabilityRules.SA1412StoreFilesAsUtf8 (SA1412) = 0 ms StyleCop.Analyzers.NamingRules.SA1301ElementMustBeginWithLowerCaseLetter (SA1301) = 0 ms StyleCop.Analyzers.NamingRules.SA1305FieldNamesMustNotUseHungarianNotation (SA1305) = 0 ms StyleCop.Analyzers.NamingRules.SA1306FieldNamesMustBeginWithLowerCaseLetter (SA1306) = 0 ms StyleCop.Analyzers.NamingRules.SA1310FieldNamesMustNotContainUnderscore (SA1310) = 0 ms StyleCop.Analyzers.NamingRules.SX1309FieldNamesMustBeginWithUnderscore (SX1309) = 0 ms StyleCop.Analyzers.NamingRules.SX1309SStaticFieldNamesMustBeginWithUnderscore (SX1309S) = 0 ms StyleCop.Analyzers.OrderingRules.SA1200UsingDirectivesMustBePlacedCorrectly (SA1200) = 0 ms StyleCop.Analyzers.OrderingRules.SA1201ElementsMustAppearInTheCorrectOrder (SA1201) = 0 ms StyleCop.Analyzers.OrderingRules.SA1202ElementsMustBeOrderedByAccess (SA1202) = 0 ms StyleCop.Analyzers.OrderingRules.SA1203ConstantsMustAppearBeforeFields (SA1203) = 0 ms StyleCop.Analyzers.OrderingRules.SA1205PartialElementsMustDeclareAccess (SA1205) = 0 ms StyleCop.Analyzers.OrderingRules.SA1206DeclarationKeywordsMustFollowOrder (SA1206) = 0 ms StyleCop.Analyzers.OrderingRules.SA1214ReadonlyElementsMustAppearBeforeNonReadonlyElements (SA1214) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists (SA1100) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1101PrefixLocalCallsWithThis (SA1101) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1107CodeMustNotContainMultipleStatementsOnOneLine (SA1107) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1108BlockStatementsMustNotContainEmbeddedComments (SA1108) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1109BlockStatementsMustNotContainEmbeddedRegions (SA1109) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1111ClosingParenthesisMustBeOnLineOfLastParameter (SA1111) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1114ParameterListMustFollowDeclaration (SA1114) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1115ParameterMustFollowComma (SA1115) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1116SplitParametersMustStartOnLineAfterDeclaration (SA1116) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1118ParameterMustNotSpanMultipleLines (SA1118) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1120CommentsMustContainText (SA1120) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1122UseStringEmptyForEmptyStrings (SA1122) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1124DoNotUseRegions (SA1124) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1126PrefixCallsCorrectly (SA1126) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1127GenericTypeConstraintsMustBeOnOwnLine (SA1127) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1128ConstructorInitializerMustBeOnOwnLine (SA1128) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1130UseLambdaSyntax (SA1130) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1131UseReadableConditions (SA1131) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1132DoNotCombineFields (SA1132) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1133DoNotCombineAttributes (SA1133) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1134AttributesMustNotShareLine (SA1134) = 0 ms StyleCop.Analyzers.ReadabilityRules.SA1139UseLiteralSuffixNotationInsteadOfCasting (SA1139) = 0 ms StyleCop.Analyzers.ReadabilityRules.SX1101DoNotPrefixLocalMembersWithThis (SX1101) = 0 ms StyleCop.Analyzers.SpacingRules.SA1002SemicolonsMustBeSpacedCorrectly (SA1002) = 0 ms StyleCop.Analyzers.SpacingRules.SA1003SymbolsMustBeSpacedCorrectly (SA1003) = 0 ms StyleCop.Analyzers.SpacingRules.SA1005SingleLineCommentsMustBeginWithSingleSpace (SA1005) = 0 ms StyleCop.Analyzers.SpacingRules.SA1008OpeningParenthesisMustBeSpacedCorrectly (SA1008) = 0 ms StyleCop.Analyzers.SpacingRules.SA1009ClosingParenthesisMustBeSpacedCorrectly (SA1009) = 0 ms StyleCop.Analyzers.SpacingRules.SA1023DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly (SA1023) = 0 ms StyleCop.Analyzers.SpacingRules.SA1025CodeMustNotContainMultipleWhitespaceInARow (SA1025) = 0 ms ```
sharwell commented 3 years ago

📝 Note that the Analyzer Summary reports CPU time and not wall clock time, so the 30 seconds would be spread out over the number of cores used for the build.

sharwell commented 3 years ago

It looks like SA1121 would benefit from being rewritten as an IOperation analyzer.

jnm2 commented 3 years ago

Total csc task time is also reported as 31 seconds. It's become a real inner loop problem which is why I started digging, and StyleCop Analyzers is the biggest contributor by an order of magnitude.

manfred-brands commented 2 years ago

I have the same issue for our main project: The SA1121 rule is standing out by a mile.

image

Looking at the code, it does a lot of text comparison. The documentaion of SyntaxKind doesn't indicate when that one is raised, maybe it is for every use of a variable.

Could this rule be limited to variable declaration (Int32 i) and static method calls (Int32.Parse) only?

sharwell commented 2 years ago

Most of the cost of SA1121 is in the call to GetSymbolInfo. This call will be eliminated for everything except certain generic arguments if the analyzer is updated to support IOperation.

manfred-brands commented 2 years ago

Ok, I will attempt a rewrite.

bjornhellander commented 2 years ago

@manfred-brands, are you still on this?

bjornhellander commented 2 years ago

I had a quick look at this and it is not clear to me how to implement SA1121 as an operation analyzer. What operations (https://learn.microsoft.com/en-us/dotnet/api/microsoft.codeanalysis.operationkind?view=roslyn-dotnet-4.3.0) would SA1121 need to handle, @sharwell? I see e.g. variable declarations in the linked page above, but I don't realize how to handle e.g. parameters, fields and method return types.

bjornhellander commented 1 year ago

@jnm2 and @manfred-brands In the solutions that you provided build performance data for, approximately how large portion of the source files define aliases? Like using MyStuff = System.Int32;

manfred-brands commented 1 year ago

@bjornhellander From the 60781 files, there are 7 files that have a using alias. Not to hide built-in types, but to differentiate between types with same name imported (Rhino.Mocks.Constraint.Is vs NUnit.Framework.Is).

bjornhellander commented 1 year ago

I think I figured out why SA1121 is so slow. Based on @manfred-brands answer, I started digging and it seemed strange that the calls to GetSymbolInfo would cost so much in his case, since it shouldn't be called that many times if there aren't loads of files with using alias statements. Eventually I saw that the syntax node action which is called to check all identifiers requires the stylecop settings object.

If I am not completely wrong, that means that without the optimizations that I am working on to fix #3634 by caching the settings, the settings file will be parsed for every single identifier found in the analyzed code. That is not good. On the bright side, completing that optimization should be much easier than re-writing SA1121. At least as a first step to re-evaluate the performance with the cache in place.