Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RoslynSource Text #1123

Merged
merged 12 commits into from
Jun 30, 2023
Merged

RoslynSource Text #1123

merged 12 commits into from
Jun 30, 2023

Conversation

TheAngryByrd
Copy link
Member

@TheAngryByrd TheAngryByrd commented Jun 21, 2023

WHAT

🤖 Generated by Copilot at a6a0682

Refactor AdaptiveFSharpLspServer to use IFSACSourceText interface for source text representation and improve readability.

🤖 Generated by Copilot at a6a0682

IFSACSourceText
Replaces NamedText now
More flexible code

🔧📝🚀

WHY

This uses the SourceText from the Microsoft.CodeAnalysis package. The Visual Studio tooling uses this. The implementation here tends to give more favorable results when it comes to memory usage and reducing Large Object Heap allocations.

I also have a very bespoke implementation I attempted awhile ago with FSharp.Data.Adaptive and handrolling a lot of text manipulation using Spans. This probably will get removed before this PR is ready.

Below are some of the benchmarks. N refers to the number of changes to a text file.

Method N Mean Error StdDev Ratio RatioSD Gen0 Gen1 Gen2 Allocated Alloc Ratio
Named_Text_changeText_everyUpdate 1 1,075.3 μs 21.15 μs 49.43 μs 1.00 0.00 398.4375 398.4375 398.4375 3776.11 KB 1.00
Roslyn_Text_changeText_everyUpdate 1 638.6 μs 10.84 μs 10.14 μs 0.62 0.04 68.3594 68.3594 68.3594 565.51 KB 0.15
Named_Text_changeText_everyUpdate 15 5,672.0 μs 108.95 μs 129.69 μs 1.00 0.00 3195.3125 3195.3125 3195.3125 26443.69 KB 1.00
Roslyn_Text_changeText_everyUpdate 15 6,379.8 μs 79.40 μs 74.27 μs 1.13 0.03 1031.2500 1031.2500 1031.2500 6647.57 KB 0.25
Named_Text_changeText_everyUpdate 50 17,874.3 μs 433.18 μs 1,277.25 μs 1.00 0.00 10187.5000 10187.5000 10187.5000 83072.79 KB 1.00
Roslyn_Text_changeText_everyUpdate 50 21,707.5 μs 417.19 μs 409.74 μs 1.26 0.08 3437.5000 3437.5000 3437.5000 21899.62 KB 0.26
Named_Text_changeText_everyUpdate 100 37,283.2 μs 738.74 μs 1,946.14 μs 1.00 0.00 20142.8571 20142.8571 20142.8571 164112.6 KB 1.00
Roslyn_Text_changeText_everyUpdate 100 43,574.5 μs 377.32 μs 352.95 μs 1.16 0.05 6833.3333 6833.3333 6833.3333 43748.23 KB 0.27
Named_Text_changeText_everyUpdate 1000 366,397.6 μs 7,224.03 μs 7,094.96 μs 1.00 0.00 200000.0000 200000.0000 200000.0000 1664182.49 KB 1.00
Roslyn_Text_changeText_everyUpdate 1000 430,151.2 μs 6,393.32 μs 5,667.51 μs 1.17 0.03 71000.0000 71000.0000 71000.0000 451027 KB 0.27

This does seem like a win. It allocates about 25% less though it does report slower for lots of rapid changes.

Also after running dotnet-trace collect -p <pid> --duration 00:00:30 --profile gc-verbose and playing around with large files, we tend to not get hit with as many Large Object Heap issues.

Things left to do:

  • See if AdaptiveSourceText is even worth it (I'll maybe do this another time)
  • Create a Factory to pivot to a different sourcetext implementation like we did with ProjectLoading
  • Cleanup benchmarks

HOW

🤖 Generated by Copilot at a6a0682

  • Refactor the source text representation to use the interface IFSACSourceText instead of the type NamedText in various functions, to allow different implementations for different editors or scenarios (link, link, link)
  • Remove unnecessary parentheses around the namedText binding in the handler function in AdaptiveFSharpLspServer.fs, to make the code more consistent and readable (link, link, link, link, link, link, link)

faster at individual lines than Roslyn SourceText but slower at whole file creation
@TheAngryByrd TheAngryByrd force-pushed the own-source-text-impl branch 2 times, most recently from 16995ae to b9e8693 Compare June 27, 2023 02:14
@TheAngryByrd TheAngryByrd force-pushed the own-source-text-impl branch 3 times, most recently from 08f7117 to 986231a Compare June 27, 2023 02:27
open FSharp.UMX
open System.Collections.Generic

let fileContents = IO.File.ReadAllText(@"C:\Users\jimmy\Repositories\public\TheAngryByrd\span-playground\Romeo and Juliet by William Shakespeare.txt")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using this a just a giant text file. Should I include it or leave as an exercise for the others?

Microsoft.CodeAnalysis.Text.TextSpan(startPosition, endPosition - startPosition)

/// A SourceText with operations commonly used in FsAutocomplete
type IFSACSourceText =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted interface for FSAC's source text impl

static member Create(path: string<LocalPath>, text, version) =
let touched =
let path = UMX.untag path
type ISourceTextFactory =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interface for pivoting between implementations.


override _.GetHashCode() =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken from Fsharp repo

Comment on lines +59 to +62
let sourceTextFactories: (string * ISourceTextFactory) list = [
"NamedText", NamedTextFactory()
"RosylinSourceText", RoslynSourceTextFactory()
]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running tests for both SourceText implementations

@TheAngryByrd TheAngryByrd marked this pull request as ready for review June 27, 2023 02:38
@TheAngryByrd
Copy link
Member Author

Formatting check is failing due to a bug in fantomas: fsprojects/fantomas#2914

@TheAngryByrd TheAngryByrd changed the title WIP: RoslynSource Text RoslynSource Text Jun 28, 2023
Copy link
Contributor

@baronfel baronfel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, how will folks opt into this? the FSAC extra args option in Ionide?

test/FsAutoComplete.Tests.Lsp/Program.fs Show resolved Hide resolved
@baronfel baronfel merged commit 87a2e9f into ionide:main Jun 30, 2023
9 checks passed
@TheAngryByrd
Copy link
Member Author

LGTM, how will folks opt into this? the FSAC extra args option in Ionide?

Yeah I gotta make an ionide side flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants