-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Further reduce Linq usage in ComponentModel.Annotations #57897
Comments
Tagging subscribers to this area: @ajcvickers, @bricelam, @roji Issue DetailsIn PR #56753 usage of Linq was reduced in System.ComponentModel.Annotations. The changes I'm proposing should:
Once these opportunities have been validated, I'll implement the changes and use benchmarks to show the effect these changes have. I understand of course that - even after initial validation - some changes may still be rejected. Here are the changes I'm proposing: AssociatedMetadataTypeTypeDescriptor
CustomValidationAttribute
FileExtensionsAttribute
Validator
ValidationAttributeStore
For those changes that are accepted, please indicate which changes - if any - can be grouped in a single PR.
|
Thanks, @drieseng. I'm not convinced throughput improvements to System.ComponentModel.Annotations matter, though I'm happy to be convinced otherwise with data. Does any of this code show on hot paths? Does it show up on startup paths where these changes will help reduce startup, maybe by reducing JIT'ing or something like that? If there are places where the use of LINQ is gratuitous, and the same functionality can be implemented without LINQ and with minimal additional (or even less) code, I'm all for replacing it. I skimmed your list and some of your examples fall into this category. With regards to linker friendliness, it's important to keep in mind that all it takes is one call anywhere in an app to a given method, and that method needs to then be kept. So if we delete all of our use of method M in order to enable M to be trimmed away but then the app uses M, it can't be trimmed away. Worse, if we delete our use of M by replacing it with a lot of custom code, not only do we now have more code to maintain, but if M does end up getting used by the app, we've actually increased code size, as now the app has to carry both M and our custom replacement for it. |
I can't help but get the impression that my email address has the wrong domain name. |
They're not. For example, it replaced use of
I don't know what that means...? |
Changes from people with the microsoft domain are just more readily accepted. I can even understand this to some degree. I was trying to give something back, but instead it appears I've been wasting mine and your time. |
From what I've seen internal suggestions are held to the same standard but much of the discussion can be had in person instead of on github. Watch some of the api review meetings on youtube and you'll see that there's a lot of pushback internally and the quality bar is strictly upheld for everyone. Some of your suggestions are good. I'd advise removing some of the smaller uses of linq in a PR and seeing what review feedback you get. Any negative reviews will have to explain their reasoning and you'll be able to use that feedback to either iterate or help you better understand the boundaries or what will be acceptable in future PR's. |
I'm sorry that's the impression you're getting; that is not what I've been trying to convey. I explicitly wrote: For the broader cases, where there are tradeoffs to be made, there needs to be good reason to churn the code. If such reasons exist, we'd also happily accept such fixes, too, but it'll involve more discussion to understand the benefits vs cost. |
@stephentoub Let me apologize for taking the feedback too negatively then. It's mostly the first paragraph that gave me the impression that even the smallest change had to be strongly motivated (more on this below). I did not, and do not, expect all the changes I identified to be validated (meaning, even considered for a PR). Is it ok if I number each change, so you can indicate for which changes you'd accept a PR? I don't want to submit 10 PRs, and get that first paragraph as feedback for each of them. I created this issue to make sure I don't implement changes that don't even have a chance of being accepted. I already mentioned this in the other PR: I'm definitely not a (heavy) user of System.ComponentModel.Annotations. I actually have close to zero benefit in improving it for myself (or even zero, unless through unintenional usage). I just though it was a low bar entry into contributing to .NET. If you expect another motivation other than the items I listed in the main description and altruism, then I'll have to disappoint you. |
Sure |
In PR #56753 usage of Linq was reduced in System.ComponentModel.Annotations.
My first attempt to reduce this further (PR #57392) failed miserably, so I'd like to first indicate some other opportunities before I spend time implementing and benchmarking these.
The changes I'm proposing should:
Once these opportunities have been validated, I'll implement the changes and use benchmarks to show the effect these changes have. I understand of course that - even after initial validation - some changes may still be rejected.
I only hope that the probability will be a lot lower.
Here are the changes I'm proposing:
AssociatedMetadataTypeTypeDescriptor
String.Join(String, IEnumerable<String>)
didn't exist.Enumerable.FirstOrDefault<TSource>(this System.Collections.Generic.IEnumerable<TSource> source)
here and just check ifType.GetMember(...)
returned an array with one or more entries.AttributeCollection.CopyTo(Array array, int index)
here to obtain array of attributes.CustomValidationAttribute
Type.GetMethod(String, BindingFlags)
to retrieve the MethodInfo. This is both a performance optimalization and a minor bug fix. After this change we’ll throw the same exception as .NET Framework.I’ll of course add a corresponding unit test.
FileExtensionsAttribute
String.Join(String, IEnumerable<String>)
here to avoid Linq.String.ToLowerInvariant()
.Validator
GetObjectPropertyValidationErrors(…)
andGetPropertyValues(…)
to return List<T> instead of respectively IEnumerable<ValidationError> and ICollection<KeyValuePair<ValidationContext, object?>>. This avoids interface dispatch and allow us to directly use the result here and here. This in turn eliminates allocation of an extra list (and theList<T>.AddRange(…)
invocations).Enumerable.Any()
.ValidationAttributeStore
For those changes that are validated, please indicate which changes - if any - can be grouped in a single PR.
The text was updated successfully, but these errors were encountered: