From 761f06e9c443591899600ba7b11a3efa388d41ec Mon Sep 17 00:00:00 2001 From: Ladi Prosek Date: Mon, 1 Nov 2021 09:01:55 +0100 Subject: [PATCH] Minor allocation optimizations / cleanup (#6983) --- .../CachingSdkResolverService.cs | 4 ++- .../SdkResolution/SdkResolverService.cs | 4 ++- src/Build/Utilities/EngineFileUtilities.cs | 11 ++----- src/Shared/FileUtilities.cs | 6 ++-- .../ResolveAssemblyReference.cs | 29 ++++++++++--------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverService.cs b/src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverService.cs index e5c4095acb9..23c505ff896 100644 --- a/src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverService.cs +++ b/src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverService.cs @@ -47,7 +47,9 @@ public override SdkResult ResolveSdk(int submissionId, SdkReference sdk, Logging else { // Get the dictionary for the specified submission if one is already added otherwise create a new dictionary for the submission. - ConcurrentDictionary> cached = _cache.GetOrAdd(submissionId, new ConcurrentDictionary>(MSBuildNameIgnoreCaseComparer.Default)); + ConcurrentDictionary> cached = _cache.GetOrAdd( + submissionId, + _ => new ConcurrentDictionary>(MSBuildNameIgnoreCaseComparer.Default)); /* * Get a Lazy if available, otherwise create a Lazy which will resolve the SDK with the SdkResolverService.Instance. If multiple projects are attempting to resolve diff --git a/src/Build/BackEnd/Components/SdkResolution/SdkResolverService.cs b/src/Build/BackEnd/Components/SdkResolution/SdkResolverService.cs index fba2c4925b1..ff98112817b 100644 --- a/src/Build/BackEnd/Components/SdkResolution/SdkResolverService.cs +++ b/src/Build/BackEnd/Components/SdkResolution/SdkResolverService.cs @@ -247,7 +247,9 @@ private void SetResolverState(int submissionId, SdkResolver resolver, object sta // Do not set state for resolution requests that are not associated with a valid build submission ID if (submissionId != BuildEventContext.InvalidSubmissionId) { - ConcurrentDictionary resolverState = _resolverStateBySubmission.GetOrAdd(submissionId, new ConcurrentDictionary(NativeMethodsShared.GetLogicalCoreCount(), _resolvers.Count)); + ConcurrentDictionary resolverState = _resolverStateBySubmission.GetOrAdd( + submissionId, + _ => new ConcurrentDictionary(NativeMethodsShared.GetLogicalCoreCount(), _resolvers.Count)); resolverState.AddOrUpdate(resolver, state, (sdkResolver, obj) => state); } diff --git a/src/Build/Utilities/EngineFileUtilities.cs b/src/Build/Utilities/EngineFileUtilities.cs index 242085521c9..40347473d2a 100644 --- a/src/Build/Utilities/EngineFileUtilities.cs +++ b/src/Build/Utilities/EngineFileUtilities.cs @@ -236,18 +236,13 @@ private static bool MatchesLazyWildcard(string fileSpec) return file => matchers.Any(m => m.Value.IsMatch(file)); } - internal class IOCache + internal sealed class IOCache { private readonly Lazy> existenceCache = new Lazy>(() => new ConcurrentDictionary(), true); - public virtual bool DirectoryExists(string directory) + public bool DirectoryExists(string directory) { - return existenceCache.Value.GetOrAdd(directory, Directory.Exists); - } - - public virtual bool FileExists(string file) - { - return existenceCache.Value.GetOrAdd(file, File.Exists); + return existenceCache.Value.GetOrAdd(directory, directory => Directory.Exists(directory)); } } } diff --git a/src/Shared/FileUtilities.cs b/src/Shared/FileUtilities.cs index 76155b33800..952fd9963d4 100644 --- a/src/Shared/FileUtilities.cs +++ b/src/Shared/FileUtilities.cs @@ -903,7 +903,7 @@ internal static bool DirectoryExistsNoThrow(string fullPath, IFileSystem fileSys fileSystem ??= DefaultFileSystem; return Traits.Instance.CacheFileExistence - ? FileExistenceCache.GetOrAdd(fullPath, fileSystem.DirectoryExists) + ? FileExistenceCache.GetOrAdd(fullPath, fullPath => fileSystem.DirectoryExists(fullPath)) : fileSystem.DirectoryExists(fullPath); } catch @@ -927,7 +927,7 @@ internal static bool FileExistsNoThrow(string fullPath, IFileSystem fileSystem = fileSystem ??= DefaultFileSystem; return Traits.Instance.CacheFileExistence - ? FileExistenceCache.GetOrAdd(fullPath, fileSystem.FileExists) + ? FileExistenceCache.GetOrAdd(fullPath, fullPath => fileSystem.FileExists(fullPath)) : fileSystem.FileExists(fullPath); } catch @@ -951,7 +951,7 @@ internal static bool FileOrDirectoryExistsNoThrow(string fullPath, IFileSystem f fileSystem ??= DefaultFileSystem; return Traits.Instance.CacheFileExistence - ? FileExistenceCache.GetOrAdd(fullPath, fileSystem.FileOrDirectoryExists) + ? FileExistenceCache.GetOrAdd(fullPath, fullPath => fileSystem.FileOrDirectoryExists(fullPath)) : fileSystem.FileOrDirectoryExists(fullPath); } catch diff --git a/src/Tasks/AssemblyDependency/ResolveAssemblyReference.cs b/src/Tasks/AssemblyDependency/ResolveAssemblyReference.cs index 2cea34c71bb..53b19c17a62 100644 --- a/src/Tasks/AssemblyDependency/ResolveAssemblyReference.cs +++ b/src/Tasks/AssemblyDependency/ResolveAssemblyReference.cs @@ -3153,23 +3153,26 @@ public override bool Execute() { return Execute ( - new FileExists(p => FileUtilities.FileExistsNoThrow(p)), - new DirectoryExists(p => FileUtilities.DirectoryExistsNoThrow(p)), - new GetDirectories(Directory.GetDirectories), - new GetAssemblyName(AssemblyNameExtension.GetAssemblyNameEx), - new GetAssemblyMetadata(AssemblyInformation.GetAssemblyMetadata), + p => FileUtilities.FileExistsNoThrow(p), + p => FileUtilities.DirectoryExistsNoThrow(p), + (p, searchPattern) => Directory.GetDirectories(p, searchPattern), + p => AssemblyNameExtension.GetAssemblyNameEx(p), + (string path, ConcurrentDictionary assemblyMetadataCache, out AssemblyNameExtension[] dependencies, out string[] scatterFiles, out FrameworkNameVersioning frameworkName) + => AssemblyInformation.GetAssemblyMetadata(path, assemblyMetadataCache, out dependencies, out scatterFiles, out frameworkName), #if FEATURE_WIN32_REGISTRY - new GetRegistrySubKeyNames(RegistryHelper.GetSubKeyNames), - new GetRegistrySubKeyDefaultValue(RegistryHelper.GetDefaultValue), + (baseKey, subkey) => RegistryHelper.GetSubKeyNames(baseKey, subkey), + (baseKey, subkey) => RegistryHelper.GetDefaultValue(baseKey, subkey), #endif - new GetLastWriteTime(NativeMethodsShared.GetLastWriteFileUtcTime), - new GetAssemblyRuntimeVersion(AssemblyInformation.GetRuntimeVersion), + p => NativeMethodsShared.GetLastWriteFileUtcTime(p), + p => AssemblyInformation.GetRuntimeVersion(p), #if FEATURE_WIN32_REGISTRY - new OpenBaseKey(RegistryHelper.OpenBaseKey), + (hive, view) => RegistryHelper.OpenBaseKey(hive, view), #endif - new GetAssemblyPathInGac(GetAssemblyPathInGac), - new IsWinMDFile(AssemblyInformation.IsWinMDFile), - new ReadMachineTypeFromPEHeader(ReferenceTable.ReadMachineTypeFromPEHeader) + (assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, fullFusionName, specificVersion) + => GetAssemblyPathInGac(assemblyName, targetProcessorArchitecture, getRuntimeVersion, targetedRuntimeVersion, fileExists, fullFusionName, specificVersion), + (string fullPath, GetAssemblyRuntimeVersion getAssemblyRuntimeVersion, FileExists fileExists, out string imageRuntimeVersion, out bool isManagedWinmd) + => AssemblyInformation.IsWinMDFile(fullPath, getAssemblyRuntimeVersion, fileExists, out imageRuntimeVersion, out isManagedWinmd), + p => ReferenceTable.ReadMachineTypeFromPEHeader(p) ); }