Open paulomorgado opened 12 months ago
Hello @paulomorgado,
You are right about the additional allocations caused by Linq. The rule has the clean code attribute clear which is defined as
The code is self-explanatory, transparently communicating its functionality. It is written in a straightforward way that minimizes ambiguity, avoiding unnecessary clever or intricate solutions.
The rule description states, "Those functions can be handled with a clearer, more concise LINQ expression instead".
So, the rule is about readability, which, in the case of Linq, always comes at the price of allocations.
All code in the hot path needs to follow different rules than "normal" code. We, in our codebase, use the PerformanceSensitiveAnalyzers of the Roslyn analyzers and apply their [PerformanceSensitive]
attribute to the hot path to indicate code, that is supposed to avoid Linq:
We could add support for that attribute to the rule, so we would not raise if the attribute is present. Would you consider this a viable solution?
Hello @martin-strecker-sonarsource,
Not giving any performance degradation under [PerformanceSensitive]
is a good idea.
But there should be a performance notice warning on diagnostics the avise to introduce performance degradations.
And a way to disable all those diagnostics. For when all the code is performance sensitive.
And a way to disable all those diagnostics.
There are a couple of exclusion mechanisms supported by our products. You can e.g. define your own profile and exclude the rule there. You can read more about exclusion options here:
I think something like category severity configuration like this is would be great:
From Overview of .NET source code analysis - Code-style analysis - Enable on build:
[*.{cs,vb}]
# Default severity for analyzer diagnostics with category 'Style' (escalated to build warnings)
dotnet_analyzer_diagnostic.category-Style.severity = warning
# IDE0040: Accessibility modifiers required (disabled on build)
dotnet_diagnostic.IDE0040.severity = silent
Our rules do have a category already so you can do this. The recommended way is to change the quality profile, though. This gives you more control and can be re-used across projects.
Is that something I can put in a .editorconfig
file?
Claiming this improves readability is a stretch. IMO the original foreach loop is far more readable than the convoluted LINQ statement.
Description
S3267 advises to use LINQ To Objects in loops, which is a sever performance penalty.
Related information
The compliant code:
has 2 delegate instantiations with invocations per item.
Whereas the non-compliant code has no delegate instantiation or invocation.
Besides that, because LINQ To Objects is being used, instead of the non heap allocating enumerator for
List<T>
being used, an heap allocating enumerator generated by the iterator inside LINQ To Objects.Todo by @martin-strecker-sonarsource
[PerformanceSensitiveAttribute]
(The attribute must be namedPerformanceSensitive
but does not necessarily need to be from theMicrosoft.CodeAnalysis.PerformanceSensitiveAnalyzers
package). TheAttributeTragets
of PerformanceSensitiveAttribute should be respected.