ReSharper 高效攻略 – 将 ReSharper 从进程中取出
在上一篇ReSharper性能系列文章中,我们讲述了Visual Studio和ReSharper的复杂性和历史,并确定了性能下降的原因之一在于Visual Studio是32位进程。在本文中,我们将会讲述如何克服这个限制。
在本系列中:
-
ReSharper性能简介系列
-
将ReSharper从进程中取出
-
组件合成、即时编译、UI线程
-
ReSharper 2018.1和2018.1.1的性能改进
让我们深入了解一下吧!
Roslyn和ReSharper
我们已经研究了32位进程的局限性,并且明白只有这么多内存可供消耗。
因此也许有人会问:为什么JetBrains仍使用ReSharper构建自己的语言引擎呢?
为什么不只用Roslyn,这样内存中就只有一个而不是两个引擎了?而带来的好处是,也许ReSharper开发会变得更快?
不这样做的原因有很多,如我们在ReSharper和Roslyn Q&A中所述。
一个更好的问题是:为了解决32位工作集的限制而更换一台润滑更好的引擎是否值得?还要过多久,这种更换也会遇到边界限制?
当然有更好的办法……
Microservices! (微服务)
(采用子进程的形式)
如何克服可用内存的限制?和所有事情一样,答案是微服务。
Visual Studio正在逐步过渡到带有很多子进程的进程,每个子进程都可以消耗其所需的内存。
这种架构有很多优点:每个子进程都有自己的线程池,可以由操作系统在不同的CPU内核上运行。
每个子进程还有自己的内存空间和自己的垃圾回收器。
在我们的跨平台.NET IDE – Rider中使用了同样的方法,IDE只是UI和宿主进程,而很多繁重的工作都发生在子进程中,这会导致性能发生翻天覆地的改善。
运行多个进程的确会带来一些其他挑战。
如何保持同步?
必须处理编辑器中的所有按键操作吗?
当我们键入类名然后删除它时, 它是否必须在两个进程中都存在?
我们在Rider中使用的反应分布式通信协议可能解答了这些问题。
JetBrains正在研究将ReSharper作为Visual Studio的一个子进程而不是主进程的一部分。
异步加载ReSharper VSPackage
在使ReSharper运行自己的进程之后,我们可以改进必须保留在Visual Studio进程中的位的加载。
我们仍将可以呈现菜单、显示重构对话框,并跟踪编辑器。
Visual Studio真的只是Visual Studio Shell,它加载很多VSPackage实例,其中包含语言功能和使其成为IDE的具体工具。
几乎Visual Studio安装程序中的每个复选框都代表这类VSPackage,而ReSharper是可以加载的另一个VSPackage实例。
只有当某些上下文需要某个包时,Visual Studio才执行延迟加载。
更新的Visual Studio版本也允许异步加载VSPackage,将此工作移动到后台线程。
JetBrains正在研究将ReSharper作为异步VSPackage加载。
结论
在本文中,我们讲述了改进ReSharper性能的一种方法:将它从进程中取出。
这带来很多好处:Visual Studio和ReSharper都在自己的进程中运行,有自己的线程池和内存空间。此外,我们正在研究在Visual Studio中异步加载ReSharper。但这些解决方案都未达到完美。
还有其他领域可以改进,我们将在下一篇文章中讲述这些内容!
如果您遇到性能问题,切记查看Visual Studio性能指南 (ReSharper 2017.3+),还有我们的知识库文章加快ReSharper(和Visual Studio)。
如果您遇到可以重现的具体的性能问题,而且您愿意收集并发送性能问题快照给我们,我们将深表感激。
博客文章将ReSharper从进程中取出 – ReSharper性能系列将在.NET工具博客上首发。