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:
Родитель
2a2cacccf0
Коммит
8d76214e2a
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче