From f0899c2591195f661bac1d6ed765e05c80135714 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Thu, 1 Oct 2020 19:05:33 -0700 Subject: [PATCH 1/2] Initial parallel parsing commit --- src/fsharp/fsc.fs | 28 ++++++++++++++++++++-------- src/fsharp/lexhelp.fs | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index f6b9767b862..12286fe8b02 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -19,6 +19,7 @@ open System.IO open System.Reflection open System.Text open System.Threading +open System.Threading.Tasks open Internal.Utilities open Internal.Utilities.Collections @@ -1841,14 +1842,25 @@ let main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, let inputs = try let isLastCompiland, isExe = sourceFiles |> tcConfig.ComputeCanContainEntryPoint - isLastCompiland |> List.zip sourceFiles - // PERF: consider making this parallel, once uses of global state relevant to parsing are cleaned up - |> List.choose (fun (filename: string, isLastCompiland) -> - let pathOfMetaCommandSource = Path.GetDirectoryName filename - match ParseOneInputFile(tcConfig, lexResourceManager, ["COMPILED"], filename, (isLastCompiland, isExe), errorLogger, (*retryLocked*)false) with - | Some input -> Some (input, pathOfMetaCommandSource) - | None -> None - ) + let sourceFiles = isLastCompiland |> List.zip sourceFiles |> Array.ofSeq + + let parallelOptions = ParallelOptions() + parallelOptions.MaxDegreeOfParallelism <- Environment.ProcessorCount + + if parallelOptions.MaxDegreeOfParallelism > sourceFiles.Length then + parallelOptions.MaxDegreeOfParallelism <- sourceFiles.Length + + let results = Array.zeroCreate sourceFiles.Length + Parallel.For(0, sourceFiles.Length, parallelOptions, fun i -> + results.[i] <- + let (filename: string, isLastCompiland) = sourceFiles.[i] + let pathOfMetaCommandSource = Path.GetDirectoryName filename + match ParseOneInputFile(tcConfig, lexResourceManager, ["COMPILED"], filename, (isLastCompiland, isExe), errorLogger, (*retryLocked*)false) with + | Some input -> Some (input, pathOfMetaCommandSource) + | None -> None) |> ignore + results + |> Array.choose id + |> List.ofArray with e -> errorRecoveryNoRange e exiter.Exit 1 diff --git a/src/fsharp/lexhelp.fs b/src/fsharp/lexhelp.fs index 26a50de6f28..a205e5f5ddd 100644 --- a/src/fsharp/lexhelp.fs +++ b/src/fsharp/lexhelp.fs @@ -39,7 +39,7 @@ type LightSyntaxStatus(initial:bool,warn:bool) = /// Manage lexer resources (string interning) [] type LexResourceManager(?capacity: int) = - let strings = new System.Collections.Generic.Dictionary(defaultArg capacity 1024) + let strings = new System.Collections.Concurrent.ConcurrentDictionary(Environment.ProcessorCount, defaultArg capacity 1024) member x.InternIdentifierToken(s) = match strings.TryGetValue s with | true, res -> res From 76b77fc99eb048b789a4778567b1b2e85efe0847 Mon Sep 17 00:00:00 2001 From: Will Smith Date: Fri, 2 Oct 2020 10:17:24 -0700 Subject: [PATCH 2/2] Update src/fsharp/fsc.fs Co-authored-by: Saul Rennison --- src/fsharp/fsc.fs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 12286fe8b02..23d48da3998 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1844,11 +1844,7 @@ let main0(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, let isLastCompiland, isExe = sourceFiles |> tcConfig.ComputeCanContainEntryPoint let sourceFiles = isLastCompiland |> List.zip sourceFiles |> Array.ofSeq - let parallelOptions = ParallelOptions() - parallelOptions.MaxDegreeOfParallelism <- Environment.ProcessorCount - - if parallelOptions.MaxDegreeOfParallelism > sourceFiles.Length then - parallelOptions.MaxDegreeOfParallelism <- sourceFiles.Length + let parallelOptions = ParallelOptions(MaxDegreeOfParallelism=min Environment.ProcessorCount sourceFiles.Length) let results = Array.zeroCreate sourceFiles.Length Parallel.For(0, sourceFiles.Length, parallelOptions, fun i -> @@ -2262,4 +2258,3 @@ let mainCompile typecheckAndCompile (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, defaultCopyFSharpCore, exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) -