From c69f43395b832952a6299e86755e29d6a2e0e722 Mon Sep 17 00:00:00 2001 From: Marius Ungureanu Date: Mon, 26 Mar 2018 20:22:08 +0300 Subject: [ProjectModel] Optimize allocations on evaluation Avoid enumerator boxing and avoid allocating a string for all the property imports --- .../ImportSearchPathExtensionNode.cs | 9 +++++++ .../DefaultMSBuildEngine.cs | 28 +++++++++++++++------- .../MSBuildEvaluationContext.cs | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) (limited to 'main/src/core') diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ImportSearchPathExtensionNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ImportSearchPathExtensionNode.cs index 7835f1cc35..bb3875187d 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ImportSearchPathExtensionNode.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ImportSearchPathExtensionNode.cs @@ -36,6 +36,15 @@ namespace MonoDevelop.Projects.Extensions [NodeAttribute ("property")] public string Property { get; set; } + string msbuildProperty; + internal string MSBuildProperty { + get { + if (msbuildProperty == null) + msbuildProperty = "$(" + Property + ")"; + return msbuildProperty; + } + } + string path; public new string Path { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs index 90adb3c67b..031bd2492f 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs @@ -1042,12 +1042,12 @@ namespace MonoDevelop.Projects.MSBuild return CreateEvaluatedItem (context, project, project.Project, item, context.EvaluateString (item.Include)); } - IEnumerable GetImportedProjects (ProjectInfo project, MSBuildImport import) + IReadOnlyList GetImportedProjects (ProjectInfo project, MSBuildImport import) { List prefProjects; if (project.ImportedProjects.TryGetValue (import, out prefProjects)) return prefProjects; - return Enumerable.Empty (); + return Array.Empty (); } void AddImportedProject (ProjectInfo project, MSBuildImport import, ProjectInfo imported) @@ -1068,10 +1068,12 @@ namespace MonoDevelop.Projects.MSBuild void Evaluate (ProjectInfo project, MSBuildEvaluationContext context, MSBuildImport import, bool evalItems) { - if (evalItems) { - // Properties have already been evaluated - // Don't evaluate properties, only items and other elements - foreach (var p in GetImportedProjects (project, import)) { + if (evalItems) { + // Properties have already been evaluated + // Don't evaluate properties, only items and other elements + var importedProjects = GetImportedProjects (project, import); + for (int i = 0; i < importedProjects.Count; ++i) { + var p = importedProjects [i]; EvaluateProject (p, new MSBuildEvaluationContext (context), true); @@ -1115,9 +1117,19 @@ namespace MonoDevelop.Projects.MSBuild // In that case, look in fallback search paths if (keepSearching) { - foreach (var prop in context.GetProjectImportSearchPaths ()) { - if (import.Project.IndexOf ("$(" + prop.Property + ")", StringComparison.OrdinalIgnoreCase) == -1) + // Short-circuit if we don't have an import that is done via a property. + int propertyStart = import.Project.IndexOf ("$(", StringComparison.Ordinal); + if (propertyStart == -1) + return; + + var importSearchPaths = context.GetProjectImportSearchPaths (); + for (int i = 0; i < importSearchPaths.Count; ++i) { + var prop = importSearchPaths [i]; + + // Start searching from where the property was found. + if (import.Project.IndexOf (prop.MSBuildProperty, propertyStart, StringComparison.OrdinalIgnoreCase) == -1) continue; + files = GetImportFiles (project, context, import, prop.Property, prop.Path, out resolvedSdksPath, out keepSearching); if (files != null) { foreach (var f in files) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs index 7afbf74a5e..0f37e215f9 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs @@ -227,7 +227,7 @@ namespace MonoDevelop.Projects.MSBuild get { return project; } } - public IEnumerable GetProjectImportSearchPaths () + public IReadOnlyList GetProjectImportSearchPaths () { if (parentContext != null) return parentContext.GetProjectImportSearchPaths (); -- cgit v1.2.3