Improve roslyn MetadataReference performance

- Add additional Caching in CachingMetadataReference to avoid poking the filesystem for last write time when the metadata of a MetadataReference, which is done a lot of times when looking up for symbols via the SymbolFinder class.
- Added parallelization of a MetadataReference caching
This commit is contained in:
Jérôme Laban 2019-03-13 10:27:20 -04:00
Родитель 2a2cacccf0
Коммит 8d76214e2a
2 изменённых файлов: 27 добавлений и 13 удалений

Просмотреть файл

@ -59,20 +59,24 @@ namespace Uno.SourceGeneration.Host
private void PreInit()
{
// Used by MSB.ProjectCollection
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Parallelize the initialization of the MefServices graph (Used by AdHocWorkspace)
Microsoft.CodeAnalysis.Host.Mef.MefHostServices.DefaultHost.ToString();
// Pre-load known references
if (_environment.ReferencePath != null)
Task.Run(() =>
{
foreach (var reference in _environment.ReferencePath)
// Used by MSB.ProjectCollection
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Parallelize the initialization of the MefServices graph (Used by AdHocWorkspace)
Microsoft.CodeAnalysis.Host.Mef.MefHostServices.DefaultHost.ToString();
// Pre-load known references in parallel
if (_environment.ReferencePath != null)
{
_metadataResolver.ResolveReference(Path.GetFileName(reference), Path.GetDirectoryName(reference), new MetadataReferenceProperties());
_environment
.ReferencePath
.AsParallel()
.Select(r => _metadataResolver.ResolveReference(Path.GetFileName(r), Path.GetDirectoryName(r), new MetadataReferenceProperties()))
.ToArray();
}
}
});
}
public string[] Generate()

Просмотреть файл

@ -110,8 +110,9 @@ namespace Uno.SourceGeneration.Host.Server
internal sealed class CachingMetadataReference : PortableExecutableReference
{
private static readonly MetadataAndSymbolCache s_mdCache = new MetadataAndSymbolCache();
private Metadata _metadata;
public CachingMetadataReference(string fullPath, MetadataReferenceProperties properties)
public CachingMetadataReference(string fullPath, MetadataReferenceProperties properties)
: base(properties, fullPath)
{
}
@ -123,7 +124,16 @@ namespace Uno.SourceGeneration.Host.Server
protected override Metadata GetMetadataImpl()
{
return s_mdCache.GetMetadata(FilePath, Properties);
if (_metadata == null)
{
// Locally cache the value for this instance, when a resolver will get the file a subsequent time
// the cache will validate for a newer version of the metadata. This avoids re-reading the target
// file time while a given compilation is running.
// See https://github.com/dotnet/roslyn/issues/34072
_metadata = s_mdCache.GetMetadata(FilePath, Properties);
}
return _metadata;
}
protected override PortableExecutableReference WithPropertiesImpl(MetadataReferenceProperties properties)