Introducing the ReSharper performance series

With every ReSharper update, we get questions around performance. Some users notice a slightly slower solution load, others see a minor indexing lag, and others get bugged by a yellow notification bar stating “Extension ‘JetBrains ReSharper Ultimate’ likely caused 9 seconds of unresponsiveness. Disabling it may improve your experience.” – and yes, we have seen higher values there, too.

We hear you. We use ReSharper to develop ReSharper. It may not always be visible, but we are working hard on improving ReSharper performance. And because those changes aren’t always visible, we are starting a blog series about the minor and major changes that are in the works.

We’ll touch on some high-level things, but will also open up the hood and see what happens underneath.

In this series:

Note these posts will be long – there’s a lot of context involved. So let’s start at the beginning – a little bit of history!

Visual Studio and ReSharper

Visual Studio services many developers across Windows, the Web and multiple Cloud and Mobile platforms. It builds on years of history, and has gone through a number of changes over the years. New languages and frameworks came about, often with new development paradigms. The C# compiler moved to Roslyn, adding additional code analysis and refactoring features to Visual Studio.

Development workloads are always in motion, and thanks to Visual Studio having a very extensible architecture, it has always been able to follow new development trends and provide a rich IDE experience.

Plugging into that extensible architecture, ReSharper increases Visual Studio value by extending existing features and by providing additional capabilities like additional code analysis rules and quick-fixes, structural search-and-replace, 55 refactorings, improved code generation, build and debugging features, and much, much more – an overview is available in our ReSharper vs. Visual Studio overview.

An additional consideration is that ReSharper doesn’t only extend the latest Visual Studio version. Many of our customers are using previous Visual Studio versions for a variety of reasons, making ReSharper extend Visual Studio 2010 SP1, 2012 (all three updates), 2013 (all five updates), 2015 (all three updates), and all of the updates 2017 continuously brings.

This means ReSharper still knows about project.json, has knowledge of lightweight solution load which was introduced and then removed, and many more.

The point we are trying to make here is that both products are complex in nature. And there is even more complexity! Have you ever thought about how difficult it is for an IDE to work with incomplete, broken code that does not compile? It is what happens all the time while we are writing lines of code… And that broken code can be refactored! We can navigate around our project! There’s code completion! It’s awesome, really, that Visual Studio and ReSharper can do this!

I, for one, would not want to go back to the basic tools we had in 1998 – having a rich IDE is just too good!

The 32-bit cage match

One thing has not changed since Visual Studio’s inception: it has always been a 32-bit process. This means that in the best circumstances (running as a 32-bit application on a 64-bit operating system), it can only consume close to 3 GB of memory. In practice, only about 2.5 GB of memory can be used.

Not all of that space can be used efficiently, as there’s “reserved memory” as well: memory that is pre-allocated for future use, used for communication between processes, used for mapping files from disk, chunks that do not have enough free space to be used by the .NET runtime to store its objects, …

In the remaining usable memory space, it has to host its own functionality, the Roslyn engine, and when ReSharper is installed, the ReSharper engine, too. As well as all actions and commands available throughout the IDE.

If at any point we profile Visual Studio with ReSharper enabled, we can see that a lot of time is spent doing just Garbage Collection (GC) – a good 12% of the time in this snapshot! (this was during a solution load)

dotTrace timeline snapshot of Visual Studio startup with ReSharper

(Note: as we can see in this snapshot, Visual Studio startup spends a lot of time doing Just-in-Time (JIT) compilation as well – we will touch on that later in this series.)

In 32-bit processes, GC may run more often than is optimal, for example when there is a memory shortage. In a 64-bit process, more objects may have to be sweeped but this will be done less often and at more optimal times because the ceiling is not being reached.

“If only Microsoft would compile Visual Studio as a 64-bit executable! It would ensure there’s more available memory, and everything would be fixed! Right?” Many have been asking exactly that: please make Visual Studio a 64-bit executable. The first comment in that thread mentions this will not be easy. Assemblies may become larger, and the IDE may actually become slower because there is even more memory to manage (garbage collection may take more time and resources).

How is that possible? There are many areas where Visual Studio and ReSharper consume memory, but let’s focus on one of many examples. Both Visual Studio and ReSharper keep a syntax tree in memory. All of the code in our project is parsed into a semantic model and a syntax tree. Roslyn uses immutable trees, which is great when working with syntax, but also means code under churn creates a lot of objects that may not be short-lived and will have to be garbage collected. ReSharper has a different approach with its PSI and how syntax and semantics are modeled and processed in memory.

Some syntax and semantic structures will be generated once and won’t change. So next to short-lived objects, Roslyn, as well as ReSharper end up with having a number of long-lived objects as well. And where do those go in the .NET runtime? Generation 2. And generation 2 garbage collection usually takes longer because the objects have more roots where they are referenced.

Gen2 managed heap usage

Is this bad? Not at all. Both Roslyn and ReSharper re-use already known information about our code, keeping the objects containing that information in memory. Our IDE would slow down if these had to be re-created all the time, so keeping them in memory is a good approach. It’s just that when the garbage collector runs, it may take a little longer.

Moving to a 64-bit process will only make the number of objects to scan during a garbage collection (GC) larger, possibly making GC pauses take more time.

There are many more considerations around a 64-bit Visual Studio, such as having to ensure the entire ecosystem of extensions for Visual Studio is also ported to 64-bit. Another interesting article in that regard is Visual Studio: Why is there no 64 bit version? (yet).

In short, it seems 64-bit will not happen soon, if ever. This means Microsoft as well as JetBrains and other extension authors have to resort to clever techniques to provide better performance.

Conspiracy theories!

In this introductory post, let’s get one more question out of the way… Many have been asking us whether JetBrains is intentionally slowing down ReSharper to promote Rider. This is definitely not the case!

Rider can not exist without ReSharper (they share their codebase), and any work we do on one product influences and benefits the other. Having both products running in a different environment (32-bit Visual Studio vs. 64-bit Rider) brings benefits, too. Any problem that exists around performance and memory in ReSharper and Rider can stay unnoticed in Rider but will most probably surface very clearly in ReSharper. Fixes will always benefit both.

ReSharper and Rider target the same audience of .NET developers, and we want to offer them a choice. Some prefer Visual Studio and ReSharper/ReSharper Ultimate, others prefer Rider. We welcome teams to work in mixed environments, where some may use vanilla Visual Studio, other use ReSharper Ultimate in Visual Studio, and another group uses Rider.

Conclusion

In this post, we determined that both IDE’s like Visual Studio and tools like ReSharper are complex in nature. We’ve looked at some of the histories of both products, and have seen that some of that history is not easily changed.

But that does not mean things can’t be improved! In our next blog post, we will look at a number of high-level improvements JetBrains is doing to make ReSharper better and faster. And no, the answer is not as simple as switching to Roslyn… Stay tuned for (much) more!

In the meanwhile, if you are experiencing performance issues, make sure to check the Performance guide for Visual Studio (ReSharper 2017.3+) as well as our KB article Speeding up ReSharper (and Visual Studio). If you have a specific performance issue you can reproduce, we’d appreciate if you could collect a performance snapshot and send it over.

PS: You may also enjoy the talk “.NET Performance Issues and Optimizations in Visual Studio / Roslyn / ReSharper / Rider” by Kirill Skrygan, our Rider development lead.

This entry was posted in How-To's and tagged , , , , , , . Bookmark the permalink.

45 Responses to Introducing the ReSharper performance series

  1. Mike-EEE says:

    Wait… so Rider is 64-bit while Visual Studio is not? Good reminder to check out Rider again now that the cement on it has settled a bit. :)

  2. Howard says:

    Its not just startup time, when using smart intellisense time-to-character UI performance in VS2017 is really slow on any low powered (15W) cpu, like in all those ultrabooks (im using Dell xps 13 with i7-8550u). I have to turn off R# intellisense on that machine, and use ctrl+alt+space shortcut to invoke it on demand.
    Thanks for all the perf improvements, looking forward seeing them in action!

  3. tobi says:

    Resharper performance has been a major issue for 1-2 years now. I remember 5 years ago it was slow, then there was a successful performance push then it got slow again.

    Typing is very slow these days! It’s fast in toy console projects but in 100kloc solutions typing is ridiculously slow. I only tolerate this (as opposed to uninstalling Resharper) because typing is just 5% of the time I spend with the IDE. But it’s really bad. Pressing dot after an identifier often times out. This seems to be a fairly simple/cheap operation to me.

    The completion windows is so slow that Resharper sometimes times out and does not show it at all. This means that when typing I cannot rely on it being available. This causes my typing patterns to change to be more inefficient since I cannot know whether pressing space will complete the word or not.

    It seems certain code patterns are problematic for performance. I think LINQ queries make the current file very slow for some reason.

    I followed the performance guide that you recently put out. I keep solution wide analysis enabled, though. Can this cause such major slowdown?!

    Resharper is so awesome but perf has really gotten very very bad. I appreciate your efforts.

  4. James Trudel says:

    What I want, more than anything, is to be able to disable Resharper at a solution and/or project level.

    I do frequent development in c# codebase, as well as a VERY large c++ project that completely chokes Resharper. I currently have to disable Resharper before opening it. Makes it a serious pain to deal with.

  5. Igor says:

    It’s not true that you use resharper with VS. The resharper team has long since switched to the reader.

  6. X says:

    What if you move some of the service out of process? I believe visual assist does that

  7. Chris says:

    For those experiencing slow typing responsiveness, I was able to get improvement by reverting 2018.1.1 back to 2018.1.

  8. Markus Hastreiter says:

    The next blog posts better be good because I’ve reached my breaking point and I’m actively looking for alternatives. I really like and depend on some ReSharper features (like Base symbols/Derived symbols for navigation). I just can’t take it much longer. The only suggestions I’m reading are “well, turn off everything that makes either Visual Studio or ReSharper nice to use” so that I would end up with hardly more than a simple text editor.
    This is not an acceptable solution for me.
    I’m not using CodeLens (it’s deactivated) and I’m not using solution-wide analysis (also disabled) and typing is still often slow (it varies between “tolerable” and delays of 4+ seconds between typing and seeing the text in the editor).
    I’m often working with a 100 project solution (roughly 1m LoC (C#)).
    Since the latest update (ReSharper 2018.1.1), I’m getting a new yellow VS notification: “We’ve noticed that extension ‘JetBRains ReSharper 2018.1.1’ is slowing typing performance.”
    So, any improvement is appreciated.

  9. Dev says:

    > Many have been asking us whether JetBrains is intentionally slowing down ReSharper to promote Rider.

    They probably referred to slowing down the development rather than performance. It’s obviously absolutely the case: from shared codebase hindrance to workforce focus dilution.

  10. Pingback: Dew Drop - May 29, 2018 (#2734) - Morning Dew

  11. Rogier says:

    Typing is so slow in this new version that I’m going to disable R# for the moment or revert to an older version. I litteraly have to wait for characters to appear on screen. This is totally unworkable, I have submitted a snapshot with feedback center.

  12. Paul Irwin says:

    I’d like to commend the ReSharper team for finally addressing the performance concerns in such an open and honest way. I use this tool daily and I have to keep convincing myself not to uninstall it when I run into performance issues, which is constantly. Many of my colleagues have stopped using it because of performance. And I’ve even had VS crashes due to running out of memory. If ReSharper gets no additional features in the next year but fixes the performance, I’ll be thrilled as a customer and will enthusiastically recommend it to my colleagues again.

    For others on here, in the meantime, the best tip I’ve found is to not have too many tabs open. Once my tab bar fills up, I close all but the current document. That’s the only thing that has kept things performing anything close to reasonably with my large solution.

  13. James G says:

    One of the key issues I’ve been having has to do with the TypeScript/JavaScript handling that causes white screen of death to occur on solution load. Disabling the feature in R# sped up performance a lot. (I’ve already got a ticket in with perf snapshot and the identified where the issue is).

  14. Avareto says:

    Sorry, but I really don’t care about the details. I only can confirm that ReSharper is unacceptable slow, regardless of switching your analyses features on or off.
    ReSharper simply lost its core feature: increasing developers productivity! Today opposite is the truth.
    Sorry, but I deactivated ReSharper in VS after the last update. Hopefully not forever!

  15. David Smith says:

    So what is your short term advice for all the “ReSharper ultimate is slowing down …” messages that pop up several times a day even after following the recommendations in your KB article? Is it to always ignore them?

    Also, the recommendation to disable source control integration is a bit of a non-starter.

    • Short term if you don’t experience any noticeable lag, you can ignore the warnings.

      • David Smith says:

        I definitely get all kinds of warnings from Visual Studio about Resharper affecting solution load times and typing. Sometimes Visual Studio shows multiple messages suggesting I should disable Resharper. On the performance page, everything is set to “fix silently” except for source control integration.

  16. Pingback: The ReSharper performance series: conspiracy theories, Visual Studio/Roslyn and ReSharper, the 32-bit cage match, async loading, out of process, and more. - How to Code .NET

  17. Pingback: ReSharper 高效攻略 | JetBrains中国

  18. As a coder and business owner, who’s prime customer is government, we have very little control over the selection of IDE, tools, and libraries. Most of the time we can’t use ReSharper on agency machines. I have used ReSharper on our company machines faithfully for more than 10 years but decided not to renew any of our licenses this year. My staff has been complaining about it, I have found it to be causing more coding errors than it fixed because of the performance issues. Turning off its features is not a solution. I haven’t recommended it to my clients since VS2017 RC1. We stuck with you for the past two years hoping for better performance which has not come. We uninstalled ReSharper this past May and our licenses just expired. Its hard to get a new customer and 10x harder to get one back. I hope that others who stay with you are rewarded.

    • Yesterday, ReSharper 2018.2 was released where a lot of focus went into performance already (solution load should be noticeably faster), and efforts described in this series are ongoing. Keep an eye on our blog if you are interested in what is happening and how we are solving certain issues – if not for winning you back then it could serve as a story from in the field (which I personally always find interesting).

      Thanks for reaching out, Larry, and thank you for your feedback!

Leave a Reply

Your email address will not be published. Required fields are marked *