diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index f6b9767b862..23d48da3998 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,21 @@ 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(MaxDegreeOfParallelism=min Environment.ProcessorCount 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 @@ -2250,4 +2258,3 @@ let mainCompile typecheckAndCompile (ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, reduceMemoryUsage, defaultCopyFSharpCore, exiter, errorLoggerProvider, tcImportsCapture, dynamicAssemblyCreator) - 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