diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj index 4bdb142e62b..d1187649935 100644 --- a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FSharp.Compiler.Benchmarks.fsproj @@ -17,6 +17,7 @@ + diff --git a/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs new file mode 100644 index 00000000000..746f81065b7 --- /dev/null +++ b/tests/benchmarks/FCSBenchmarks/CompilerServiceBenchmarks/FileCascadeBenchmarks.fs @@ -0,0 +1,118 @@ +namespace FSharp.Compiler.Benchmarks + +open System +open System.IO +open System.Text +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.AbstractIL.ILBinaryReader +open BenchmarkDotNet.Attributes +open FSharp.Compiler.Benchmarks +open Microsoft.CodeAnalysis.Text +open BenchmarkDotNet.Order +open BenchmarkDotNet.Mathematics + +[] +module private CascadeProjectHelpers = + + let createProject files projectFilename = + { + ProjectFileName = projectFilename + ProjectId = None + SourceFiles = files + OtherOptions = [|"--optimize+" |] + ReferencedProjects = [||] + IsIncompleteTypeCheckEnvironment = false + UseScriptResolutionRules = false + LoadTime = DateTime() + UnresolvedReferences = None + OriginalLoadReferences = [] + Stamp = Some 0L (* set the stamp to 0L on each run so we don't evaluate the whole project again *) + } + + let baselineModule = + $""" +module Benchmark0 +let returnValue = 5 +let myFunc0 () = 5""" + + let generateSourceCode number = + $""" +module Benchmark%i{number} +open Benchmark%i{number-1} +let myFunc%i{number} () = myFunc%i{number-1}() +//$COMMENTAREA$""" + +[] +[] +[] +[] +type FileCascadeBenchmarks() = + let mutable project : FSharpProjectOptions option = None + + let getProject() = project.Value + + let checker = FSharpChecker.Create(projectCacheSize = 5, enableParallelCheckingWithSignatureFiles = true, parallelReferenceResolution = true) + let filesToCreate = 64 + + let mutable finalFileContents = SourceText.ofString "" + + [] + member _.Setup() = + let projectFolder = Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(),"CascadeBenchmarkProject")) + if(projectFolder.Exists) then + do projectFolder.Delete(recursive=true) + do Directory.CreateDirectory(projectFolder.FullName) |> ignore + + let inProjectFolder fileName = Path.Combine(projectFolder.FullName,fileName) + + File.WriteAllText(inProjectFolder "Benchmark0.fs",baselineModule) + for i = 1 to filesToCreate do + File.WriteAllText(inProjectFolder $"Benchmark%i{i}.fs", generateSourceCode i) + + let dllFileName = inProjectFolder "CascadingBenchMark.dll" + let allSourceCodeFiles = [| for i in 0 .. filesToCreate -> inProjectFolder $"Benchmark%i{i}.fs"|] + let x = createProject allSourceCodeFiles dllFileName + project <- Some x + finalFileContents <- generateSourceCode filesToCreate |> SourceText.ofString + + + member x.ChangeFile(fileIndex:int, action) = + let project = getProject() + let fileName = project.SourceFiles.[fileIndex] + let fullOriginalSource = File.ReadAllText(fileName) + try + File.WriteAllText(fileName, fullOriginalSource.Replace("$COMMENTAREA$","$FILEMODIFIED")) + action() + finally + File.WriteAllText(fileName,fullOriginalSource) + + member x.CheckFinalFile () = + let project = getProject() + let lastFile = project.SourceFiles |> Array.last + checker.ParseAndCheckFileInProject(lastFile,999,finalFileContents,project) + + [] + member x.ParseProjectAsIs() = + x.CheckFinalFile() + + [] + member x.ParseProjectWithFullCacheClear() = + checker.ClearCache([getProject()]) + checker.InvalidateConfiguration(getProject()) + x.CheckFinalFile() + + [] + member x.ParseProjectWithChangingFirstFile() = + x.ChangeFile(fileIndex=0, action= fun () -> x.CheckFinalFile()) + + [] + member x.ParseProjectWithChanging25thPercentileFile() = + x.ChangeFile(fileIndex=filesToCreate/4, action= fun () -> x.CheckFinalFile()) + + [] + member x.ParseProjectWithChangingMiddleFile() = + x.ChangeFile(fileIndex=filesToCreate/2, action= fun () -> x.CheckFinalFile()) \ No newline at end of file