Skip to content

Commit

Permalink
Sequentialize GetAllUsesOfAllSymolsInFile (#10357)
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermp authored Nov 6, 2020
1 parent 65da35e commit b0fac9d
Show file tree
Hide file tree
Showing 18 changed files with 772 additions and 169 deletions.
18 changes: 10 additions & 8 deletions src/fsharp/service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1872,16 +1872,18 @@ type FSharpCheckFileResults
member __.DependencyFiles = dependencyFiles

member __.GetAllUsesOfAllSymbolsInFile(?cancellationToken: CancellationToken ) =
threadSafeOp
(fun () -> [| |])
threadSafeOp
(fun () -> Seq.empty)
(fun scope ->
let cenv = scope.SymbolEnv
[| for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do
for symbolUse in symbolUseChunk do
cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested())
if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then
let symbol = FSharpSymbol.Create(cenv, symbolUse.Item)
yield FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |])
seq {
for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do
for symbolUse in symbolUseChunk do
cancellationToken |> Option.iter (fun ct -> ct.ThrowIfCancellationRequested())
if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then
let symbol = FSharpSymbol.Create(cenv, symbolUse.Item)
FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range)
})

member __.GetUsesOfSymbolInFile(symbol:FSharpSymbol, ?cancellationToken: CancellationToken) =
threadSafeOp
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/service/FSharpCheckerResults.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ type public FSharpCheckFileResults =
member GetFormatSpecifierLocationsAndArity : unit -> (range*int)[]

/// Get all textual usages of all symbols throughout the file
member GetAllUsesOfAllSymbolsInFile : ?cancellationToken: CancellationToken -> FSharpSymbolUse[]
member GetAllUsesOfAllSymbolsInFile : ?cancellationToken: CancellationToken -> seq<FSharpSymbolUse>

/// Get the textual usages that resolved to the given symbol throughout the file
member GetUsesOfSymbolInFile : symbol:FSharpSymbol * ?cancellationToken: CancellationToken -> FSharpSymbolUse[]
Expand Down
199 changes: 101 additions & 98 deletions src/fsharp/service/ServiceAnalysis.fs

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions src/fsharp/service/ServiceAnalysis.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

namespace FSharp.Compiler.SourceCodeServices

open FSharp.Compiler.NameResolution
open FSharp.Compiler.Range
open FSharp.Compiler.SyntaxTree

module public UnusedOpens =

Expand All @@ -24,9 +22,9 @@ module public SimplifyNames =
}

/// Get all ranges that can be simplified in a file
val getSimplifiableNames : checkFileResults: FSharpCheckFileResults * getSourceLineStr: (int -> string) -> Async<SimplifiableRange list>
val getSimplifiableNames : checkFileResults: FSharpCheckFileResults * getSourceLineStr: (int -> string) -> Async<seq<SimplifiableRange>>

module public UnusedDeclarations =

/// Get all unused declarations in a file
val getUnusedDeclarations : checkFileResults: FSharpCheckFileResults * isScriptFile: bool -> Async<range list>
val getUnusedDeclarations : checkFileResults: FSharpCheckFileResults * isScriptFile: bool -> Async<seq<range>>
Original file line number Diff line number Diff line change
Expand Up @@ -21450,7 +21450,7 @@ FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.Sourc
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpDeclarationListInfo GetDeclarationListInfo(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SourceCodeServices.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SourceCodeServices.AssemblySymbol]]])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpFindDeclResult GetDeclarationLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpMethodGroup GetMethods(Int32, Int32, System.String, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[System.String]])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpSymbolUse[] GetAllUsesOfAllSymbolsInFile(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.SourceCodeServices.FSharpSymbolUse] GetAllUsesOfAllSymbolsInFile(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpSymbolUse[] GetUsesOfSymbolInFile(FSharp.Compiler.SourceCodeServices.FSharpSymbol, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken])
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpToolTipText`1[Internal.Utilities.StructuredFormat.Layout] GetStructuredToolTipText(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Int32)
FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults: FSharp.Compiler.SourceCodeServices.FSharpToolTipText`1[System.String] GetToolTipText(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Int32)
Expand Down Expand Up @@ -24992,7 +24992,7 @@ FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange: Void .ctor(r
FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange: range Range
FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange: range get_Range()
FSharp.Compiler.SourceCodeServices.SimplifyNames: FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange
FSharp.Compiler.SourceCodeServices.SimplifyNames: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange]] getSimplifiableNames(FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String])
FSharp.Compiler.SourceCodeServices.SimplifyNames: Microsoft.FSharp.Control.FSharpAsync`1[System.Collections.Generic.IEnumerable`1[FSharp.Compiler.SourceCodeServices.SimplifyNames+SimplifiableRange]] getSimplifiableNames(FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String])
FSharp.Compiler.SourceCodeServices.SourceFile: Boolean IsCompilable(System.String)
FSharp.Compiler.SourceCodeServices.SourceFile: Boolean MustBeSingleFileProject(System.String)
FSharp.Compiler.SourceCodeServices.Structure+Collapse+Tags: Int32 Below
Expand Down Expand Up @@ -25356,7 +25356,7 @@ FSharp.Compiler.SourceCodeServices.UntypedParseImpl: Microsoft.FSharp.Core.FShar
FSharp.Compiler.SourceCodeServices.UntypedParseImpl: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryFindExpressionIslandInPosition(pos, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+ParsedInput])
FSharp.Compiler.SourceCodeServices.UntypedParseImpl: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Range+pos,System.Boolean]] TryFindExpressionASTLeftOfDotLeftOfCursor(pos, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+ParsedInput])
FSharp.Compiler.SourceCodeServices.UntypedParseImpl: System.String[] GetFullNameOfSmallestModuleOrNamespaceAtPoint(ParsedInput, pos)
FSharp.Compiler.SourceCodeServices.UnusedDeclarations: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Range+range]] getUnusedDeclarations(FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults, Boolean)
FSharp.Compiler.SourceCodeServices.UnusedDeclarations: Microsoft.FSharp.Control.FSharpAsync`1[System.Collections.Generic.IEnumerable`1[FSharp.Compiler.Range+range]] getUnusedDeclarations(FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults, Boolean)
FSharp.Compiler.SourceCodeServices.UnusedOpens: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Range+range]] getUnusedOpens(FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults, Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String])
FSharp.Compiler.SourceCodeServices.XmlDocComment: Microsoft.FSharp.Core.FSharpOption`1[System.Int32] isBlank(System.String)
FSharp.Compiler.SourceCodeServices.XmlDocParser: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SourceCodeServices.XmlDocable] getXmlDocables(FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTree+ParsedInput])
Expand Down
28 changes: 14 additions & 14 deletions tests/benchmarks/Benchmarks.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CompilerServiceBenchmarks", "CompilerServiceBenchmarks\CompilerServiceBenchmarks.fsproj", "{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "..\..\src\fsharp\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj", "{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "..\src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "..\..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{A2E3D114-10EE-4438-9C1D-2E15046607F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -22,18 +22,18 @@ Global
{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Proto|Any CPU.Build.0 = Release|Any CPU
{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}.Release|Any CPU.Build.0 = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Proto|Any CPU.Build.0 = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.Build.0 = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Proto|Any CPU.Build.0 = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Proto|Any CPU.Build.0 = Debug|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD3108C-8CDC-48E3-8CD3-B50E4F2E72A4}.Release|Any CPU.Build.0 = Release|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Proto|Any CPU.Build.0 = Debug|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A2E3D114-10EE-4438-9C1D-2E15046607F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@
</PropertyGroup>

<ItemGroup>
<None Include="decentlySizedStandAloneFile.fsx" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup />

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
<PackageReference Include="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="2.9.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj" />
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj" />
<ProjectReference Include="..\..\..\src\fsharp\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj" />
<ProjectReference Include="..\..\..\src\fsharp\FSharp.Core\FSharp.Core.fsproj" />
</ItemGroup>

</Project>
65 changes: 59 additions & 6 deletions tests/benchmarks/CompilerServiceBenchmarks/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open System.Text
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.Text
open FSharp.Compiler.Range
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
Expand Down Expand Up @@ -123,12 +124,14 @@ let function%s (x: %s) =
let z = x + y
z""" moduleName moduleName moduleName moduleName

let decentlySizedStandAloneFile = File.ReadAllText(Path.Combine(__SOURCE_DIRECTORY__, "decentlySizedStandAloneFile.fsx"))

[<MemoryDiagnoser>]
type CompilerService() =

let mutable checkerOpt = None

let mutable sourceOpt = None
let mutable assembliesOpt = None
let mutable decentlySizedStandAloneFileCheckResultOpt = None

let parsingOptions =
{
Expand All @@ -141,8 +144,6 @@ type CompilerService() =
IsExe = false
}

let mutable assembliesOpt = None

let readerOptions =
{
pdbDirPath = None
Expand All @@ -168,6 +169,18 @@ type CompilerService() =
System.AppDomain.CurrentDomain.GetAssemblies()
|> Array.map (fun x -> (x.Location))
|> Some

| _ -> ()

match decentlySizedStandAloneFileCheckResultOpt with
| None ->
let options, _ =
checkerOpt.Value.GetProjectOptionsFromScript("decentlySizedStandAloneFile.fsx", SourceText.ofString decentlySizedStandAloneFile)
|> Async.RunSynchronously
let _, checkResult =
checkerOpt.Value.ParseAndCheckFileInProject("decentlySizedStandAloneFile.fsx", 0, SourceText.ofString decentlySizedStandAloneFile, options)
|> Async.RunSynchronously
decentlySizedStandAloneFileCheckResultOpt <- Some checkResult
| _ -> ()

[<Benchmark>]
Expand Down Expand Up @@ -292,6 +305,8 @@ type CompilerService() =
// If set to 3, it will be almost as slow as re-evaluating all project and it's projects references on setup; this could be a bug or not what we want.
this.TypeCheckFileWith100ReferencedProjectsRun()

member val TypeCheckFileWithNoReferencesOptions = createProject "MainProject" []

[<IterationCleanup(Target = "TypeCheckFileWith100ReferencedProjects")>]
member this.TypeCheckFileWith100ReferencedProjectsCleanup() =
this.TypeCheckFileWith100ReferencedProjectsOptions.SourceFiles
Expand All @@ -314,7 +329,45 @@ type CompilerService() =
checker.ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients()
ClearAllILModuleReaderCache()

[<Benchmark>]
member this.SimplifyNames() =
match decentlySizedStandAloneFileCheckResultOpt with
| Some checkResult ->
match checkResult with
| FSharpCheckFileAnswer.Aborted -> failwith "checker aborted"
| FSharpCheckFileAnswer.Succeeded results ->
let sourceLines = decentlySizedStandAloneFile.Split ([|"\r\n"; "\n"; "\r"|], StringSplitOptions.None)
let ranges = SimplifyNames.getSimplifiableNames(results, fun lineNum -> sourceLines.[Line.toZ lineNum]) |> Async.RunSynchronously
ignore ranges
()
| _ -> failwith "oopsie"

[<Benchmark>]
member this.UnusedOpens() =
match decentlySizedStandAloneFileCheckResultOpt with
| Some checkResult ->
match checkResult with
| FSharpCheckFileAnswer.Aborted -> failwith "checker aborted"
| FSharpCheckFileAnswer.Succeeded results ->
let sourceLines = decentlySizedStandAloneFile.Split ([|"\r\n"; "\n"; "\r"|], StringSplitOptions.None)
let decls = UnusedOpens.getUnusedOpens(results, fun lineNum -> sourceLines.[Line.toZ lineNum]) |> Async.RunSynchronously
ignore decls
()
| _ -> failwith "oopsie"

[<Benchmark>]
member this.UnusedDeclarations() =
match decentlySizedStandAloneFileCheckResultOpt with
| Some checkResult ->
match checkResult with
| FSharpCheckFileAnswer.Aborted -> failwith "checker aborted"
| FSharpCheckFileAnswer.Succeeded results ->
let decls = UnusedDeclarations.getUnusedDeclarations(results, true) |> Async.RunSynchronously
ignore decls // should be 16
()
| _ -> failwith "oopsie"

[<EntryPoint>]
let main argv =
let _ = BenchmarkRunner.Run<CompilerService>()
let main _ =
BenchmarkRunner.Run<CompilerService>() |> ignore
0
Loading

0 comments on commit b0fac9d

Please sign in to comment.