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
Avoid temporary list allocations and specify list capacities in TaskItem #7055
Avoid temporary list allocations and specify list capacities in TaskItem #7055
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't actually relevant to your PR, but I noticed a couple instances of github.com/microsoft/msbuild later in this file. Clean-up of that optional.
@@ -929,7 +929,12 @@ public ICollection MetadataNames | |||
{ | |||
get | |||
{ | |||
List<string> names = new List<string>((List<string>)CustomMetadataNames); | |||
List<string> names = new List<string>(capacity: MetadataCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this is only really an improvement if MetadataCount is very fast—which it currently might not be.
Also, is there some convenient method like:
return MetadataCollection.Count.Union(FileUtilities.ItemSpecModifiers.All);
?
All
is an array, so I don't think so, but thought I'd check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MetadataCount
has been updated to be much faster. Please take another look and see if you feel this needs further work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said Count but meant Keys.
return MetadataCollection.Keys.Concat(FileUtilities.ItemSpecModifiers.All);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's possible, though we'd need to convert the IEnumerable<>
to an ICollection
. Calling ToList
or ToArray
is going to result in potentially multiple redundant allocations, as the resulting collection size is not known from the enumerator produced by Concat
.
By allocating a list up-front with the needed capacity, that overhead is avoided and no waste occurs in the backing arrays.
It would be possible to make this allocate one fewer object by using string[]
directly, rather than List<string>
.
Fixed in e9eb4f6. There are 267 other such URLs though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed a couple instances of github.com/microsoft/msbuild later in this file. Clean-up of that optional.
Fixed in e9eb4f6. There are 267 other such URLs though.
Oops, I'll file a PR to fix the rest. Thank you!
@@ -929,7 +929,12 @@ public ICollection MetadataNames | |||
{ | |||
get | |||
{ | |||
List<string> names = new List<string>((List<string>)CustomMetadataNames); | |||
List<string> names = new List<string>(capacity: MetadataCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said Count but meant Keys.
return MetadataCollection.Keys.Concat(FileUtilities.ItemSpecModifiers.All);
?
### Context As @Forgind and @drewnoakes pointed out, we still have links to [github.com/microsoft/msbuild](https://github.com/microsoft/msbuild) in the tree. ### Changes Made Replaced [github.com/microsoft/msbuild](https://github.com/microsoft/msbuild) with [github.com/dotnet/msbuild](https://github.com/dotnet/msbuild). Except for the two occurrences fixed in #7055. ### Testing Build, CI
These duplicated statements were probably intended to validate that the equality implementation is commutative.
The previous code confused me. I thought the comment was the variable name, which would suggest the instance would be immutable. In fact, the opposite is true. Using a named argument avoids that confusion.
The use of `as` suggests some kind of runtime type checking is involved, and that it may fail. In fact, the type is statically known to implement the interface, so direct assignment is sufficient. There should be no runtime change here as the compiler appears to optimise the check away. I just find this form of the code clearer.
The repo was moved from the 'microsoft' org to the 'dotnet' org.
Required rewriting some of ProjectItemInstance.TaskItem.Equals.
There was only one usage. As the property is not cheap to call, inline it for further optimisation opportunities.
Internally it optimises for ICollection<>, reserving enough capacity in one hit, then using CopyTo to copy data.
fdc7bf7
to
eab716d
Compare
I've force-pushed an update that's rebased on main, drops those commits which did not consider overriding metadata, added test coverage for metadata on the task item, and have optimised what seems safe and worth doing, based on API usage. The next step will be to reduce churn of temporary values in immutable collections when copying sets of metadata around by adding new batch operations. I'll hold off until this and #7085 to land in whatever form they may. |
Context
Noticed while browsing code.
Changes Made
List<>
objects in several casesList<>
capacities to avoid temporaries during construction and wasted space in resultas
type checks with direct type conversionTesting
Unit tests.
Notes
May be easier to review each commit separately.