Reduce ImmutableDictionary.Comparers allocations#5744
Reduce ImmutableDictionary.Comparers allocations#5744rainersigwald merged 5 commits intodotnet:masterfrom
Conversation
Fixes dotnet#5736 by keeping a prototype `ImmutableDictionary`-with-comparer around using the `MSBuildNameIgnoreCaseComparer`, which is the primary comparer used for all these dictionaries in MSBuild.
|
Yes, it should be easy, just use VS to open a solution considering Net Core projects, and after loading finished. Take a 32 bit dump, and use perf view to open the dump file, with which you can check the number of instances, or you can use windbg too. In either case, find ProjectItemInstance and check the usage below it.
…Sent from my phone
On Sep 17, 2020, at 2:56 PM, Rainer Sigwald <notifications@github.com> wrote:
Fixes #5736<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fissues%2F5736&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911359385&sdata=0KYI8kmenJ0DsOyFntTSEuoqeAvoR%2FParMZvavx%2BxPQ%3D&reserved=0> by keeping a prototype ImmutableDictionary-with-comparer
around using the MSBuildNameIgnoreCaseComparer, which is the primary
comparer used for all these dictionaries in MSBuild.
Second commit adds OrdinalIgnoreCase too--that is all that I found in our codebase.
@lifengl<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Flifengl&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911359385&sdata=gaA9mHEo11uod8YcLuxSLItuzZ1pIlgmg3kh3BE32Ro%3D&reserved=0>, is there an easy way to replicate your results so I can confirm that this hits everything?
________________________________
You can view, comment on, or merge this pull request online at:
#5744<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911369380&sdata=iUZXY4nw82%2BpR1uIO2uikI1rFPve%2FTHvBIqpke4pIUQ%3D&reserved=0>
Commit Summary
* Reduce ImmutableDictionary.Comparers allocations
* Do OrdinalIgnoreCase too
File Changes
* M src/Shared/CopyOnWriteDictionary.cs<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744%2Ffiles%23diff-95c9dfe6bfe845c2a4b34a984ea94f80&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911369380&sdata=v82%2FBgPzEzzD2Ten40x4l1nlTg3ttB1HePRy7INgnhs%3D&reserved=0> (28)
* M src/Tasks/Microsoft.Build.Tasks.csproj<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744%2Ffiles%23diff-4d3fc7780500131817fceb95ddcea3fe&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911369380&sdata=LjsaeLx0S%2BKdZXmFy2BL3eAfReHAg1eU2h8ABvPMfmU%3D&reserved=0> (2)
Patch Links:
* #5744.patch<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744.patch&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911379373&sdata=yxo2XcKYZSy7%2BCMpAz8xLGI9Lfq90GU4WcL1TqFAsf4%3D&reserved=0>
* #5744.diff<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744.diff&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911379373&sdata=kiXcw9URJk4qtQvDuOs%2BgbD6hZrroSMPK9hnU3ysmpU%3D&reserved=0>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fdotnet%2Fmsbuild%2Fpull%2F5744&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911389371&sdata=PI5xEsNYGm62rH0LWxjwBlWTvijewomwmEffckO2uLE%3D&reserved=0>, or unsubscribe<https://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FACYZNQSXYEDL5DCF36UBSMLSGKAY3ANCNFSM4RRB6NQA&data=02%7C01%7C%7Ccdbce8d4b8b64c6bb76b08d85b5488fb%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637359765911389371&sdata=6GwDsyClplVYYcjiqrSp3lS8ojHZzhy3ZcSOKgdmf7U%3D&reserved=0>.
|
src/Shared/CopyOnWriteDictionary.cs
Outdated
| #if NET35 | ||
| return ImmutableDictionary.Create<K, V>(keyComparer); | ||
| #else | ||
| return typeof(K) == typeof(string) && keyComparer is MSBuildNameIgnoreCaseComparer |
There was a problem hiding this comment.
nits:
- Make
MSBuildNameIgnoreCaseComparersealed to future-proof the is-a check? typeof(K) == typeof(string)looks redundant, there's no wayKcould be something else ifkeyComparerisMSBuildNameIgnoreCaseComparer
There was a problem hiding this comment.
I tried and failed to convince the type system that that typeof was unnecessary. Ideally we'd run this logic only when K is string but I'm not aware of a way to do that.
There was a problem hiding this comment.
I want to be able to say string.Empty is K, but that would match with object, IComparable, etc...
There was a problem hiding this comment.
Sealing MSBuildNameIgnoreCaseComparer breaks the build--I guess because the compiler currently doesn't know that passing a MSBuildNameIgnoreCaseComparer implies that typeof(K) == typeof(string)? When sealed, I get
error CS0030: Cannot convert type 'Microsoft.Build.Collections.MSBuildNameIgnoreCaseComparer' to 'System.Collections.Generic.IEqualityComparer<K>'
What I'd really like is a specialized implementation of this for K==string, but there's no way to do so that I'm aware of.
There was a problem hiding this comment.
Hmm, though there may be another option. Looks like the only places we use CopyOnWriteDictionary with K != string are in tests . . . maybe just drop the generic?
|
Checked with privates: -7bee5ad8 115953 1855248 System.Collections.Immutable.ImmutableDictionary`2+Comparers[[System.String, mscorlib],[Microsoft.Build.Execution.ProjectMetadataInstance, Microsoft.Build]]
+138f0578 3 48 System.Collections.Immutable.ImmutableDictionary`2+Comparers[[System.String, mscorlib],[Microsoft.Build.Execution.ProjectMetadataInstance, Microsoft.Build]]Thanks for the catch @lifengl! |
Fixes dotnet#5736 by keeping a prototype `ImmutableDictionary`-with-comparer around using the `MSBuildNameIgnoreCaseComparer`, which is the primary comparer used for all these dictionaries in MSBuild. `OrdinalIgnoreCase` is also used and gets a special case too. To make the type system happier, it was easiest to drop the `K` generic parameter to the type and hard-code it to `string`--all internal non-test uses were already doing that.
Fixes #5736 by keeping a prototype
ImmutableDictionary-with-compareraround using the
MSBuildNameIgnoreCaseComparer, which is the primarycomparer used for all these dictionaries in MSBuild.
Second commit adds
OrdinalIgnoreCasetoo--that is all that I found in our codebase.@lifengl, is there an easy way to replicate your results so I can confirm that this hits everything?