提交 8ea6a8f5 编写于 作者: J Jason Malinowski 提交者: GitHub

Merge pull request #14569 from jasonmalinowski/package-loading-time-improvements

Package loading time improvements
......@@ -42,7 +42,7 @@ public static void ResetLogger()
/// <summary>
/// let one such as ETA to set logger for the service layer
/// </summary>
internal static void SetLogger(IOptionService optionsService, string loggerName)
internal static void SetLogger(IGlobalOptionService optionsService, string loggerName)
{
if (loggerName == null)
{
......@@ -90,12 +90,12 @@ private static FunctionId GetFunctionId(string functionId)
return (FunctionId)Enum.Parse(typeof(FunctionId), functionId);
}
private static ILogger GetLogger(IOptionService optionsService, string loggerName)
private static ILogger GetLogger(IGlobalOptionService optionsService, string loggerName)
{
switch (loggerName)
{
case "EtwLogger":
return new EtwLogger(Logger.GetLoggingChecker(optionsService));
return new EtwLogger(optionsService);
case "TraceLogger":
return new TraceLogger(Logger.GetLoggingChecker(optionsService));
default:
......
......@@ -22,7 +22,7 @@ public TraceLogger()
{
}
public TraceLogger(IOptionService optionService)
public TraceLogger(IGlobalOptionService optionService)
: this(Logger.GetLoggingChecker(optionService))
{
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.VisualStudio.LanguageServices.Setup
{
/// <summary>
/// This interface allows the host to set up a telemetry service during package initialization.
/// </summary>
internal interface IRoslynTelemetrySetup
{
void Initialize(IServiceProvider serviceProvider);
}
}
......@@ -33,7 +33,14 @@ internal sealed class LanguageSettingsPersister : ForegroundThreadAffinitizedObj
private readonly IComEventSink _textManagerEvents2Sink;
private readonly IBidirectionalMap<string, Guid> _languageMap;
/// <summary>
/// The mapping between language names and Visual Studio language service GUIDs.
/// </summary>
/// <remarks>
/// This is a map between string and <see cref="Tuple{Guid}"/> rather than just to <see cref="Guid"/>
/// to avoid a bunch of JIT during startup. Generics of value types like <see cref="Guid"/> will have to JIT
/// but the ngen image will exist for the basic map between two reference types, since those are reused.</remarks>
private readonly IBidirectionalMap<string, Tuple<Guid>> _languageMap;
/// <remarks>
/// We make sure this code is from the UI by asking for all serializers on the UI thread in <see cref="HACK_AbstractCreateServicesOnUiThread"/>.
......@@ -48,16 +55,16 @@ internal sealed class LanguageSettingsPersister : ForegroundThreadAffinitizedObj
_optionService = optionService;
// TODO: make this configurable
_languageMap = BidirectionalMap<string, Guid>.Empty.Add(LanguageNames.CSharp, Guids.CSharpLanguageServiceId)
.Add(LanguageNames.VisualBasic, Guids.VisualBasicLanguageServiceId)
.Add("TypeScript", new Guid("4a0dddb5-7a95-4fbf-97cc-616d07737a77"))
.Add("F#", new Guid("BC6DD5A5-D4D6-4dab-A00D-A51242DBAF1B"))
.Add("Xaml", new Guid("CD53C9A1-6BC2-412B-BE36-CC715ED8DD41"));
_languageMap = BidirectionalMap<string, Tuple<Guid>>.Empty.Add(LanguageNames.CSharp, Tuple.Create(Guids.CSharpLanguageServiceId))
.Add(LanguageNames.VisualBasic, Tuple.Create(Guids.VisualBasicLanguageServiceId))
.Add("TypeScript", Tuple.Create(new Guid("4a0dddb5-7a95-4fbf-97cc-616d07737a77")))
.Add("F#", Tuple.Create(new Guid("BC6DD5A5-D4D6-4dab-A00D-A51242DBAF1B")))
.Add("Xaml", Tuple.Create(new Guid("CD53C9A1-6BC2-412B-BE36-CC715ED8DD41")));
foreach (var languageGuid in _languageMap.Values)
{
var languagePreferences = new LANGPREFERENCES3[1];
languagePreferences[0].guidLang = languageGuid;
languagePreferences[0].guidLang = languageGuid.Item1;
// The function can potentially fail if that language service isn't installed
if (ErrorHandler.Succeeded(_textManager.GetUserPreferences4(pViewPrefs: null, pLangPrefs: languagePreferences, pColorPrefs: null)))
......@@ -100,7 +107,7 @@ private void RefreshLanguageSettings(LANGPREFERENCES3[] langPrefs)
this.AssertIsForeground();
string languageName;
if (_languageMap.TryGetKey(langPrefs[0].guidLang, out languageName))
if (_languageMap.TryGetKey(Tuple.Create(langPrefs[0].guidLang), out languageName))
{
foreach (var option in _supportedOptions)
{
......@@ -238,7 +245,7 @@ public bool TryPersist(OptionKey optionKey, object value)
return false;
}
Guid languageServiceGuid;
Tuple<Guid> languageServiceGuid;
if (!_languageMap.TryGetValue(optionKey.Language, out languageServiceGuid))
{
......@@ -247,7 +254,7 @@ public bool TryPersist(OptionKey optionKey, object value)
}
var languagePreferences = new LANGPREFERENCES3[1];
languagePreferences[0].guidLang = languageServiceGuid;
languagePreferences[0].guidLang = languageServiceGuid.Item1;
Marshal.ThrowExceptionForHR(_textManager.GetUserPreferences4(null, languagePreferences, null));
SetValueForOption(optionKey.Option, ref languagePreferences[0], value);
......
......@@ -30,6 +30,7 @@
using static Microsoft.CodeAnalysis.Utilities.ForegroundThreadDataKind;
using Task = System.Threading.Tasks.Task;
using Microsoft.CodeAnalysis.Options;
using Microsoft.VisualStudio.LanguageServices.Telemetry;
namespace Microsoft.VisualStudio.LanguageServices.Setup
{
......@@ -69,11 +70,7 @@ protected override void Initialize()
// Ensure the options persisters are loaded since we have to fetch options from the shell
componentModel.GetExtensions<IOptionPersister>();
var telemetrySetupExtensions = componentModel.GetExtensions<IRoslynTelemetrySetup>();
foreach (var telemetrySetup in telemetrySetupExtensions)
{
telemetrySetup.Initialize(this);
}
RoslynTelemetrySetup.Initialize(this);
// set workspace output pane
_outputPane = new WorkspaceFailureOutputPane(this, _workspace);
......
......@@ -165,7 +165,6 @@
<Compile Include="Implementation\Workspace\VisualStudioNavigationOptions.cs" />
<Compile Include="Implementation\Workspace\VisualStudioNavigationOptionsProvider.cs" />
<Compile Include="Implementation\Workspace\VisualStudioProjectCacheHostServiceFactory.cs" />
<Compile Include="IRoslynTelemetrySetup.cs" />
<Compile Include="Packaging\Interop\SVsRemoteControlService.cs" />
<Compile Include="Packaging\IPackageServicesProxy.cs" />
<Compile Include="Storage\VisualStudioPersistentStorageLocationService.cs" />
......
......@@ -11,26 +11,18 @@
namespace Microsoft.VisualStudio.LanguageServices.Telemetry
{
[Export(typeof(IRoslynTelemetrySetup))]
internal class RoslynTelemetrySetup : IRoslynTelemetrySetup
internal static class RoslynTelemetrySetup
{
public void Initialize(IServiceProvider serviceProvider)
public static void Initialize(IServiceProvider serviceProvider)
{
var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel));
var workspace = componentModel.GetService<VisualStudioWorkspace>();
// initialize host context on UI thread.
var projectTypeLookup = workspace.Services.GetService<IProjectTypeLookupService>();
// set initial logger
var optionService = workspace.Services.GetService<IOptionService>();
var loggingChecker = Logger.GetLoggingChecker(optionService);
var optionService = componentModel.GetService<IGlobalOptionService>();
var telemetryService = serviceProvider.GetService(typeof(SVsTelemetryService)) as IVsTelemetryService;
Logger.SetLogger(
AggregateLogger.Create(
CodeMarkerLogger.Instance,
new EtwLogger(loggingChecker),
new EtwLogger(optionService),
new VSTelemetryLogger(telemetryService),
new VSTelemetryActivityLogger(telemetryService),
Logger.GetLogger()));
......
......@@ -14,7 +14,7 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages
[Guid(Guids.RoslynOptionPagePerformanceLoggersIdString)]
internal class PerformanceLoggersPage : AbstractOptionPage
{
private IOptionService _optionService;
private IGlobalOptionService _optionService;
protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider)
{
......@@ -22,8 +22,7 @@ protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider s
{
var componentModel = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel));
var workspace = componentModel.GetService<VisualStudioWorkspace>();
_optionService = workspace.Services.GetService<IOptionService>();
_optionService = componentModel.GetService<IGlobalOptionService>();
}
return new InternalOptionsControl(nameof(LoggerOptions), serviceProvider);
......
......@@ -12,25 +12,25 @@ namespace Microsoft.CodeAnalysis.Internal.Log
/// </summary>
internal sealed class EtwLogger : ILogger
{
private readonly Func<FunctionId, bool> _loggingChecker;
private readonly Lazy<Func<FunctionId, bool>> _loggingChecker;
// Due to ETW specifics, RoslynEventSource.Instance needs to be initialized during EtwLogger construction
// so that we can enable the listeners synchronously before any events are logged.
private readonly RoslynEventSource _source = RoslynEventSource.Instance;
public EtwLogger(IOptionService optionService)
: this(Logger.GetLoggingChecker(optionService))
public EtwLogger(IGlobalOptionService optionService)
{
_loggingChecker = new Lazy<Func<FunctionId, bool>>(() => Logger.GetLoggingChecker(optionService));
}
public EtwLogger(Func<FunctionId, bool> loggingChecker)
{
_loggingChecker = loggingChecker;
_loggingChecker = new Lazy<Func<FunctionId, bool>>(() => loggingChecker);
}
public bool IsEnabled(FunctionId functionId)
{
return _source.IsEnabled() && (_loggingChecker == null || _loggingChecker(functionId));
return _source.IsEnabled() && _loggingChecker.Value(functionId);
}
public void Log(FunctionId functionId, LogMessage logMessage)
......
......@@ -340,7 +340,7 @@ public static IDisposable LogBlock(FunctionId functionId, LogMessage logMessage,
return CreateLogBlock(functionId, logMessage, GetNextUniqueBlockId(), token);
}
public static Func<FunctionId, bool> GetLoggingChecker(IOptionService optionService)
public static Func<FunctionId, bool> GetLoggingChecker(IGlobalOptionService optionService)
{
var functionIds = Enum.GetValues(typeof(FunctionId)).Cast<FunctionId>();
var functionIdOptions = functionIds.ToDictionary(id => id, id => optionService.GetOption(FunctionIdOptions.GetOption(id)));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册