Art-Stea1th / Enhanced-Syntax-Highlighting

[Marketplace] Lightweight "editor classifier extension" for Visual Studio based on the async Roslyn APIs to enhanced highlighting custom tags in C# code.
https://marketplace.visualstudio.com/items?itemName=StanislavKuzmichArtStea1th.EnhancedSyntaxHighlighting
Other
76 stars 10 forks source link

Performance degradation on editing files of enormous size. #10

Open Art-Stea1th opened 6 years ago

Art-Stea1th commented 6 years ago

Because the classification is performed separately from the main thread - it shouldn't affect the performance.

To check the it - I have opened a large enough projects, such as ".NET Framework" sources, and the "Roslyn" sources in Visual Studio with this extension, it works out more quickly than the syntax highlighting built into the IDE.

I use this extension on all my devices and have not yet seen a performance degradation either on a workstation or a low-performance Windows-tablet.

However. At the moment, there are already several reviews about performance degradation.

Therefore. If you are observing the same issues yourself - it would be useful for me to learn more about some things:


At the moment, I physically have no time to fix it. As soon as I have a bit more free time - I'll fix this in the next update.

xperiandri commented 6 years ago

I was moving MVC 5 app to async methods. When I was changing method return type and added async to it performance was awful. Letter appear with 1-2 seconds delay.

Installed extensions list:

Microsoft Visual Studio Enterprise 2017 
Version 15.5.2
VisualStudio.15.Release/15.5.2+27130.2010
Microsoft .NET Framework
Version 4.7.03036

Installed Version: Enterprise

Architecture Diagrams and Analysis Tools   00369-60000-00001-AA797
Microsoft Architecture Diagrams and Analysis Tools

Visual Basic 2017   00369-60000-00001-AA797
Microsoft Visual Basic 2017

Visual C# 2017   00369-60000-00001-AA797
Microsoft Visual C# 2017

Visual C++ 2017   00369-60000-00001-AA797
Microsoft Visual C++ 2017

Visual F# 4.1   00369-60000-00001-AA797
Microsoft Visual F# 4.1

ASP.NET and Web Tools 2017   15.0.31125.0
ASP.NET and Web Tools 2017

ASP.NET Core Razor Language Services   1.0
Provides languages services for ASP.NET Core Razor.

ASP.NET Web Frameworks and Tools 2017   5.2.51007.0
For additional information, visit https://www.asp.net/

Azure App Service Tools v3.0.0   15.0.31106.0
Azure App Service Tools v3.0.0

BuildVision   2.1.0.143
Building process visualization.

Clear MEF Component Cache   1.4
Clears the Visual Studio MEF component cache to fix issues with cache corruption.

CodeRush for Roslyn   17.2.4.0
DevExpress CodeRush for Roslyn package.

CodeRush for Roslyn Tool Windows   17.2.4.0
DevExpress CodeRush for Roslyn Tool Windows package.

Common Azure Tools   1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

CSS AutoPrefixer   0.7.8
Write your CSS rules without vendor prefixes (in fact, forget about them entirely). Autoprefixer will use the data based on current browser popularity and property support to apply prefixes for you.

CSS Sorter   0.8.6
Sort CSS properties easily for better readibility and GZIP compression

CSS Tools   1.1.21
Provides additional features to the CSS editor in Visual Studio.

EditProj   1.0
This packages allows you to edit project and solution files without the need to unload them first.

Fabric.DiagnosticEvents   1.0
Fabric Diagnostic Events

File Differ   1.4.24
The easiest way to diff two files directly in Solution Explorer

GitHub.VisualStudio   2.3.6.391
A Visual Studio Extension that brings the GitHub Flow into Visual Studio.

HTML Tools   1.0.3
Productivity tools for the HTML editor

Insert GUID Command   2017.1.1
Provides commands to quickly insert GUIDs in the text editor.

JavaScript Language Service   2.0
JavaScript Language Service

JavaScript Project System   2.0
JavaScript Project System

JavaScript UWP Project System   2.0
JavaScript UWP Project System

Merq   1.1.17-rc (cba4571)
Command Bus, Event Stream and Async Manager for Visual Studio extensions.

Microsoft Azure Service Fabric Tools for Visual Studio   1.8
Microsoft Azure Service Fabric Tools for Visual Studio

Microsoft Azure Tools   2.9
Microsoft Azure Tools for Microsoft Visual Studio 2017 - v2.9.51120.3

Microsoft Continuous Delivery Tools for Visual Studio   0.3
Simplifying the configuration of continuous build integration and continuous build delivery from within the Visual Studio IDE.

Microsoft JVM Debugger   1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines

Microsoft MI-Based Debugger   1.0
Provides support for connecting Visual Studio to MI compatible debuggers

Microsoft Visual C++ Wizards   1.0
Microsoft Visual C++ Wizards

Microsoft Visual Studio Tools for Containers   1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.

Microsoft Visual Studio VC Package   1.0
Microsoft Visual Studio VC Package

Mono Debugging for Visual Studio   4.8.4-pre (3fe64e3)
Support for debugging Mono processes with Visual Studio.

NuGet Package Manager   4.5.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

Open Command Line   2.1.179
Opens a command line at the root of the project. Support for all consoles such as CMD, PowerShell, Bash etc. Provides syntax highlighting, Intellisense and execution of .cmd and .bat files.

ORuban.VSExtension.OpenOutput   1.0
Allows to open in Explorer the Output Folder for current Project

Project File Tools   1.0.1
Provides Intellisense and other tooling for XML based project files such as .csproj and .vbproj files.

RelayCommand Extension   1.0
RelayCommand Visual Studio Extension Detailed Info

SolutionIcon   1.0
Provides a drop-down box to attach to a running process.

SQL Server Data Tools   15.1.61710.120
Microsoft SQL Server Data Tools

StylerPackage Extension   1.0
StylerPackage Visual Stuido Extension Detailed Info

ToastNotifier   1.0
Show Toast Notification when Bulid completed.

TypeScript Tools   15.5.11025.1
TypeScript Tools for Microsoft Visual Studio

Visual Studio Code Debug Adapter Host Package   1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio

Visual Studio Tools for Universal Windows Apps   15.0.27128.01
The Visual Studio Tools for Universal Windows apps allow you to build a single universal app experience that can reach every device running Windows 10: phone, tablet, PC, and more. It includes the Microsoft Windows 10 Software Development Kit.

VisualStudio.Mac   1.0
Mac Extension for Visual Studio

VSPackage1 Extension   1.0
VSPackage1 Visual Studio Extension Detailed Info

WebJobs Tools v1.0.0   15.0.31201.0
WebJobs Tools v1.0.0

Xamarin   4.8.0.753 (6575bd113)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin Designer   4.8.188 (c5813fa34)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.

Xamarin.Android SDK   8.1.0.25 (HEAD/d8c6e504f)
Xamarin.Android Reference Assemblies and MSBuild support.

Xamarin.iOS and Xamarin.Mac SDK   11.6.1.2 (6857dfc)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

ZenCoding   1.2.11
Provides ZenCoding for the HTML Editor - full support for static HTML, Razor and WebForms.
Art-Stea1th commented 6 years ago

Hello. I'm apologize, but, unfortunately, I still have not been able to reproduce this issue.

Could you answer another question:

Thank you in advance.

sliptak commented 6 years ago

I also have performance issues. When changing large c# files (thousands of lines), typing and scrolling are very slow. Disabling Enhanced-Syntax-Highlighting makes it fast again.

This happens in a large Unity game with over 3000 cs files.


Microsoft Visual Studio Community 2017 Version 15.5.2 VisualStudio.15.Release/15.5.2+27130.2010 Microsoft .NET Framework Version 4.7.02556

Visual Basic 2017 00369-60000-00001-AA646 Visual C# 2017 00369-60000-00001-AA646 ASP.NET and Web Tools 2017 15.0.31125.0 CodeMaid 10.4.53 JavaScript Language Service 2.0 LineEndingsUnifierPackage Extension 1.0 NuGet Package Manager 4.5.0 TypeScript Tools 15.5.11025.1 Visual Studio Code Debug Adapter Host Package 1.0 Visual Studio Tools for Unity 3.5.0.2

Art-Stea1th commented 6 years ago

Hello sliptak.

Thank You for the additional info. At the moment I'm a little busy, but I think it will be useful in solving this issue in the future.

Regards.

sl1nk3 commented 6 years ago

Hi same problem here, The problem arises when editing large and complex files (I'd say files with more than 700 lines start to feel slow), the performance of the text editor degrades to the point where typing text becomes very sluggish (up to a second of delay for keystrokes to register on larger files).

I'm working on a rather large project, the solution contains approximatively 20+ csproj as well 30+ native cpp projects with aroun 10 thousands files.

I'm using VS2017 with Windows 10, a fairly capable Xeon workstation with 32 cores, and 32GB ram.

Thank you.

Troncho commented 6 years ago

Hi Art, first of all, this is an excellent coding enhancer!

Unfortunately, I'm detecting a massive performance degradation while writing on any C# class, that are part of a Class Library. This class library is part of a solution of about 15 projects. This particular class I'm editing has 2400 lines of code. While I'm writing comments. The editor almost stops responding. And while writing [intellisense] sensitive data on code, it also almos stops responding, too.

When I deactivate your [enhancer], things go back to normal.

BTW, I'm using VS 2017 Pro on a 24 gb ram Intel i7, Windows 10 Pro machine. CPU avg usage 20%. Memory avg usage 40%. Disk usage avg: negligible.

Thanks,

Walley7 commented 6 years ago

Having the same problem. Started used the extension a few days ago, and has been fine on large files. But all of a sudden this afternoon extreme typing lag appeared, and persisted through restarts. Disabling this extension was the only way to get rid of it.

Files in question are in the 4000-5000 line range. Seems fine on smaller files.

Interesting side note: just before this started, my visual studio seemed to weirdly sync in some settings from my home pc, as the font size changed to my home settings.

devl0f commented 6 years ago

Hey!

I would also like to finally chime in on this issue, as I mentioned it on the Q&A (https://marketplace.visualstudio.com/items?itemName=StanislavKuzmichArtStea1th.EnhancedSyntaxHighlighting#qna).

First of all, an absolutely great plugin that is really crucial to our work and how we develop our software. The only issue we have is the one related to performance and as other here have mentioned it is absolutely related to the size of the file being edited. I'm editing a file with about 800 lines and experience none to very little lag, however when switching to a different file with just over 4000 lines of code there are several seconds of delay between keystrokes and the text appearing. The issue therefore seems to grow exponentially with the number of lines in the file.

Luckily we have very few classes that are this large but they do exist (and need to stay that large). We currently get by by avoiding to work in those classes and breaking out whatever segment we're working on, but we're of course very much looking forward to any fix addressing this issue. Again, a really awesome plugin!

Art-Stea1th commented 6 years ago

Hello, thank all for such detailed answers and comments. I remember about this issue, and I want to fix and close it as soon as possible. However, at the moment I have a lot of other priorities.

We could solve this issue more quickly. You can join to the developer community as a collaborators and make your fixes to this extension, and I'll be glad to accept and merge them with the "master"-branch of the repository.

Hope for understanding. Regards.

JohnManna commented 6 years ago

Any update on this? Loved this extension until I had to edit a file with 2000+ lines. Unfortunately it becomes usable.

DustinCampbell commented 5 years ago

Hi! I took a look at the code here based on a request from somebody else.

Here's the first problem I spotted:

Because the classification is performed separately from the main thread - it shouldn't affect the performance.

While this is true, it looks to me like the computation to get the classified spans is forced whenever the editor asks for them (on the UI thread): https://github.com/Art-Stea1th/Enhanced-Syntax-Highlighting/blob/master/Extension/ASD.ESH/Classification/Classifier.cs#L46. So, the classification is computed asynchronously, but it's immediately synchronized. So, that asynchrony doesn't add anything other than overhead.

And here's the second issue:

As implemented, the classifier throws away the SnapshotSpan that's passed by the editor and always computes the classified spans for the entire buffer: https://github.com/Art-Stea1th/Enhanced-Syntax-Highlighting/blob/master/Extension/ASD.ESH/Classification/Classifier.cs#L33-L46. Instead, the classifier should use the SnapshotSpan to only compute spans for the requested parts of the buffer.

And finally:

A truly asynchronous classifier should compute the classification data and then trigger the ClassificationChanged event when there are classified spans available. It is the responsibility of the classifier to keep caches to respond to request quickly and then let the editor know when those caches change.

sharwell commented 5 years ago

Ideally this would be updated to follow the asynchronous tagging patterns seen in Roslyn's SemanticClassificationViewTaggerProvider.

nillkitty commented 5 years ago

Hi! I took a look at the code here based on a request from somebody else.

Here's the first problem I spotted:

Because the classification is performed separately from the main thread - it shouldn't affect the performance.

While this is true, it looks to me like the computation to get the classified spans is forced whenever the editor asks for them (on the UI thread): https://github.com/Art-Stea1th/Enhanced-Syntax-Highlighting/blob/master/Extension/ASD.ESH/Classification/Classifier.cs#L46. So, the classification is computed asynchronously, but it's immediately synchronized. So, that asynchrony doesn't add anything other than overhead.

And here's the second issue:

As implemented, the classifier throws away the SnapshotSpan that's passed by the editor and always computes the classified spans for the entire buffer: https://github.com/Art-Stea1th/Enhanced-Syntax-Highlighting/blob/master/Extension/ASD.ESH/Classification/Classifier.cs#L33-L46. Instead, the classifier should use the SnapshotSpan to only compute spans for the requested parts of the buffer.

And finally:

A truly asynchronous classifier should compute the classification data and then trigger the ClassificationChanged event when there are classified spans available. It is the responsibility of the classifier to keep caches to respond to request quickly and then let the editor know when those caches change.

Can you fork this and fix it for us? :) Please?

clairernovotny commented 5 years ago

As a heads-up, a PR that implements these classifications (all of them, I think), has just been merged in for VS 2019 preview 2+:

https://github.com/dotnet/roslyn/pull/31231

That doesn't help earlier versions of VS, but it's something to consider.

sharwell commented 5 years ago

I tried to implement the feature I described above by borrowing Roslyn code, but the amount of work ended up overwhelming for the time I had available.

devl0f commented 5 years ago

With Visual Studio 2019 now out on preview (as previously mentioned) I can report that with the native support of User Members (the equivalent of this extension's "User Tag") we can now develop in large files without any lag, which feels amazing. Haven't had much time with VS -19 yet so I can't vouch for the overall stability of it but as for the equivalent functionality that this extension offer it works very well.

Preview can be downloaded here: https://visualstudio.microsoft.com/vs/preview/

xperiandri commented 5 years ago

Do you mean this extension uses these features or what?

devl0f commented 5 years ago

No, VS 19 supports the same features that this extension does (as previously mentioned by @onovotny), but without the extension, i.e. natively. So there would be no point for this extension to carry on to VS 19. For us the solution to this bug was to simply upgrade to VS 19, even though it's in preview.

danielrdrigues commented 4 years ago

I had performance issue one day after enable the extension, the file wasn't large, but probably i had several tabs open, the highlight persisted, but the typing speed was lagged, so i disabled the extension and the lag was gone. Before i disabled the extension i tried restart VS, but same issue happened, the issue only disappeared after disabling the extension and restard VS. Good extension tho.

zb-z commented 4 years ago

Just a few notes: registryService is an imported pointer. Why fiddle with it and then lock? Just to pass if from a non-static to static field? Plus, simple pointer assignment == never garbled, even if it wasn't given from "above". Plus .NET gives deterministic initialization for "dynamic statics" (which you don't need here) - still without locking.

Try to do everything without Linq, definitely no PLINQ, no .AsParallel(), no Task-s, no implicit thread spawning. No GetSemanticModelAsync and associates (you are not the first running, you don't want to force a run and it's not your job to force it) - TryGetSemanticModel and then bail out if you really ever get nulls (VS is 5ns from collapse, let it die in peace :-).

Actually, something like var semanticModel = document.TryGetSemanticModel(...) GetClassifiedSpans(semanticModel, textSpan, document.Project.Solution.Workspace)

would probably be better (GetClassifiedSpansAsync has internal await-er for semanticModel which makes that Task.WhenAll a double hazard)

No switch-ing on a class pointer - extract SyntaxKind (simple int) just as you did for the SymbolKind.

Classes shouldn't be partial "just because". Exported classes shouldn't be internal. Any real reason for internal-any in a small editor plugin? Any reason for internal Extension(s) ?? You are the sole user - in one function :-))

No ConvertAll and then .ToList - make a straight list, give it back.

Why keep document and snapshot pointers ? To make GC sweat more ? :-) You get them with every call and you don't reuse them.

You get called for more or less every word parsed and rendered, you have no state - anything you touch beyond a bare metal is huge waste of time. Even tiniest things matter like doing simple

return new ClassificationSpan(new SnapshotSpan(snapshot, span.Start, span.Length), type);

instead of protracted:

return CreateSpan(span.TextSpan, type); private ClassificationSpan CreateSpan(TextSpan span, IClassificationType type) => new ClassificationSpan(new SnapshotSpan(snapshot, new Span(span.Start, span.Length)), type);

Try to compress everything into a minimal number of functions, never making a call if you don't have to, and then add [MethodImpl(MethodImplOptions.AggressiveInlining)] to whatever is left.

saad-hamani commented 4 years ago

Typing very slow performance on Visual Studio 2019 16.5.4 I have to desactivate it. Please look after a patch for this slowness.

sharwell commented 4 years ago

@zb-z For recommendations like https://github.com/Art-Stea1th/Enhanced-Syntax-Highlighting/issues/10#issuecomment-575216999, it helps to provide specific information from profiler results regarding the expected gains from each of the changes. Otherwise, you run the risk of requesting a large number of risky changes getting made to the code (which may regress behavior) only to find that many of them have little to no impact on the resulting application performance.