Skip to content
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

Performance: reduce overhead of computing full path for items from globs #2645

Open
lifengl opened this issue Oct 16, 2017 · 7 comments
Open
Labels
CPS Issues impacting CPS performance Performance-Scenario-Solution-Open This issue affects solution open performance. Priority:1 Work that is critical for the release, but we could probably ship without
Milestone

Comments

@lifengl
Copy link

lifengl commented Oct 16, 2017

Based on investigating performance trace to load Roslyn.sln, I looked into the time spent in CPS's UpdateSnapshotCoreAsync, almost 30% thread time in this function is to calculate FullPath of project items.

Because those items are coming from globs, I wonder the path is naturally normalized, and we can reduce some of the overhead here.

Name                                                                 	                                        Inc %	  Inc	           Inc Ct
microsoft.build.ni!FileUtilities.GetFullPath                        	                       28.1	          405.567	  592
+ microsoft.build.ni!FileUtilities.NormalizePath                     	                       19.3	           277.811	  267
+ system.ni!System.Text.RegularExpressions.Regex.Match(System.String)	 5.9	           84.554	  209
+ mscorlib.ni!System.IO.Path.Combine(System.String, System.String)   	 1.5	           22.189	   62
@lifengl
Copy link
Author

lifengl commented Oct 16, 2017

Include @cdmihai & @davkean to the thread. The rule snapshots logic is a slow portion of the code after the project evaluation phase.

@cdmihai
Copy link
Contributor

cdmihai commented Oct 16, 2017

Is this evaluation, or design time builds? Could you please also post more of the backtraces to see where GetFullPath is called from (preferably up to Project), or upload the perfiew trace?

@lifengl
Copy link
Author

lifengl commented Oct 16, 2017

This happens after the project evaluation inside VS. During that phase, we extra information from msbuild evaluation results based on rules defined in the project system. The overall time is much smaller than the evaluation time, so I would consider this lower priority than improving the evaluation time.

On the other side, we start to look beyond the evaluation time to see what we can do to make loading a project faster, and this turns out to be one major block we want to make more efficient during the critical path in the loading phase. I will share the Roslyn.sln loading ETW trace with you (or anyone can take this trace with PerfView).

To look into this time: Open the thread time window in perfView, (select devenv, and remove grouParts setting) and find UpdateSnapshotCoreAsync stack, and open it in the Callees window (this will aggregate time spent in this method). Use context menu to drill into it.

After that, you can see the time spent inside this function, and the top cost is inside FileUtilities.GetFullPath.

The caller of this method:

Name | Inc % | Inc | Inc Ct
-- | -- | -- | --
microsoft.build.ni!FileUtilities.GetFullPath | 28.1 | 405.567 | 592
+ microsoft.build.ni!Microsoft.Build.Shared.FileUtilities+ItemSpecModifiers.GetItemSpecModifier(System.String, System.String, System.String, System.String, System.String ByRef) | 28.1 | 405.567 | 592
+ microsoft.build.ni!Microsoft.Build.Shared.FileUtilities+ItemSpecModifiers.GetItemSpecModifier(System.String, System.String, System.String, System.String, System.String ByRef) | 22.2 | 319.395 | 454
\|+ microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetBuiltInMetadataEscaped(System.String) | 22.1 | 318.429 | 445
\|\|+ microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadataEscaped(System.String) | 22.1 | 318.429 | 445
\|\| + microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadata(System.String) | 22.1 | 318.429 | 445
\|\|  + microsoft.visualstudio.projectsystem.implementation.ni!ProjectEvaluationSubscriptionService.BuildItemsSnapshot | 22.1 | 318.429 | 445
\|+ microsoft.build.ni!Microsoft.Build.Shared.FileUtilities+ItemSpecModifiers.GetItemSpecModifier(System.String, System.String, System.String, System.String, System.String ByRef) | 0.1 | 0.966 | 9
\| + microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetBuiltInMetadataEscaped(System.String) | 0.1 | 0.966 | 9
\|  + microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadataEscaped(System.String) | 0.1 | 0.966 | 9
\|   + microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadata(System.String) | 0.1 | 0.966 | 9
\|    + microsoft.visualstudio.projectsystem.implementation.ni!ProjectEvaluationSubscriptionService.BuildItemsSnapshot | 0.1 | 0.966 | 9
+ microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetBuiltInMetadataEscaped(System.String) | 6.0 | 86.172 | 138
+ microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadataEscaped(System.String) | 6.0 | 86.172 | 138
+ microsoft.build.ni!Microsoft.Build.Execution.ProjectItemInstance+TaskItem.GetMetadata(System.String) | 6.0 | 86.172 | 138
+ microsoft.visualstudio.projectsystem.implementation!ProjectInstanceItemProperties.GetEvaluatedPropertyValue | 6.0 | 86.172 | 138

@AndyGerlicher AndyGerlicher added this to the MSBuild 15.6 milestone Nov 6, 2017
@cdmihai cdmihai added the CPS Issues impacting CPS label Jun 21, 2018
@livarcocc livarcocc modified the milestones: MSBuild 16.1, MSBuild 16.3 Aug 5, 2019
@livarcocc livarcocc modified the milestones: MSBuild 16.3, MSBuild 16.4 Aug 22, 2019
@rainersigwald rainersigwald modified the milestones: MSBuild 16.6, Backlog Mar 20, 2020
@panopticoncentral panopticoncentral added the Performance-Scenario-Solution-Open This issue affects solution open performance. label Mar 31, 2020
@panopticoncentral panopticoncentral added the Priority:1 Work that is critical for the release, but we could probably ship without label Mar 23, 2021
@rokonec
Copy link
Contributor

rokonec commented Apr 16, 2021

@ladipro Has this been addressed in your latest glob optimization? If yes please close this issue.

@ladipro
Copy link
Member

ladipro commented Apr 16, 2021

@rokonec I don't think this was addressed in the glob optimization changes. We should take a closer look at this.

@rokonec
Copy link
Contributor

rokonec commented Jan 9, 2024

@ladipro please check it out and decide if this is still something we shall invest into in close future? Currently it is P1 so we shall at least consider to lower priority here.

@ladipro
Copy link
Member

ladipro commented Jan 16, 2024

@rokonec this still seems to be actionable, I can see FileUtilities.GetFullPath taking a significant amount of time in traces. A concrete work item here would be to compare our P/Invoke implementation under FEATURE_LEGACY_GETFULLPATH with the regular Path.GetFullPath. The comments suggest that this was done to work around perf issues with pre-4.6.2 NetFx implementation, so that should be moot now. This would result in a perf improvement or at least code cleanup.

Next step would be to see if on this particular code path GetFullPath is really required or if it can be omitted / cached / optimized.

I lean towards keeping it as P1 and tackling it in one of the upcoming iterations.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CPS Issues impacting CPS performance Performance-Scenario-Solution-Open This issue affects solution open performance. Priority:1 Work that is critical for the release, but we could probably ship without
Projects
None yet
Development

No branches or pull requests

9 participants