Skip to content

Commit 3225121

Browse files
authored
Added ILReading benchmark (#6038)
* Added benchmark for ILModuleReader
1 parent 12b1d0b commit 3225121

7 files changed

Lines changed: 95 additions & 10 deletions

File tree

benchmarks/Benchmarks.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ VisualStudioVersion = 16.0.28407.52
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CompilerServiceBenchmarks", "CompilerServiceBenchmarks\CompilerServiceBenchmarks.fsproj", "{9A3C565C-B514-4AE0-8B01-CA80E8453EB0}"
77
EndProject
8-
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core", "..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
8+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "..\src\fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
99
EndProject
10-
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Private", "..\src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
10+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private", "..\src\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
1111
EndProject
1212
Global
1313
GlobalSection(SolutionConfigurationPlatforms) = preSolution

benchmarks/CompilerServiceBenchmarks/Program.fs

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
open System
22
open System.IO
3-
open BenchmarkDotNet.Attributes
4-
open BenchmarkDotNet.Running
3+
open System.Text
54
open Microsoft.FSharp.Compiler.ErrorLogger
65
open Microsoft.FSharp.Compiler.SourceCodeServices
76
open Microsoft.FSharp.Compiler.Text
8-
open System.Text
7+
open Microsoft.FSharp.Compiler.AbstractIL
8+
open Microsoft.FSharp.Compiler.AbstractIL.IL
9+
open Microsoft.FSharp.Compiler.AbstractIL.ILBinaryReader
910
open Microsoft.CodeAnalysis.Text
11+
open BenchmarkDotNet.Attributes
12+
open BenchmarkDotNet.Running
1013

1114
module private SourceText =
1215

@@ -77,8 +80,8 @@ type SourceText with
7780
member this.ToFSharpSourceText() =
7881
SourceText.weakTable.GetValue(this, Runtime.CompilerServices.ConditionalWeakTable<_,_>.CreateValueCallback(SourceText.create))
7982

80-
[<ClrJob; MemoryDiagnoser>]
81-
type CompilerServiceParsing() =
83+
[<MemoryDiagnoser>]
84+
type CompilerService() =
8285

8386
let mutable checkerOpt = None
8487

@@ -95,6 +98,17 @@ type CompilerServiceParsing() =
9598
IsExe = false
9699
}
97100

101+
let mutable assembliesOpt = None
102+
103+
let readerOptions =
104+
{
105+
pdbDirPath = None
106+
ilGlobals = mkILGlobals ILScopeRef.Local
107+
reduceMemoryUsage = ReduceMemoryFlag.No
108+
metadataOnly = MetadataOnlyFlag.Yes
109+
tryGetMetadataSnapshot = fun _ -> None
110+
}
111+
98112
[<GlobalSetup>]
99113
member __.Setup() =
100114
match checkerOpt with
@@ -105,8 +119,16 @@ type CompilerServiceParsing() =
105119
| None ->
106120
sourceOpt <- Some <| SourceText.From(File.OpenRead("""..\..\..\..\..\src\fsharp\TypeChecker.fs"""), Encoding.Default, SourceHashAlgorithm.Sha1, true)
107121
| _ -> ()
122+
123+
match assembliesOpt with
124+
| None ->
125+
assembliesOpt <-
126+
System.AppDomain.CurrentDomain.GetAssemblies()
127+
|> Array.map (fun x -> (x.Location))
128+
|> Some
129+
| _ -> ()
108130

109-
[<IterationSetup>]
131+
[<IterationSetup(Target = "Parsing")>]
110132
member __.ParsingSetup() =
111133
match checkerOpt with
112134
| None -> failwith "no checker"
@@ -124,7 +146,59 @@ type CompilerServiceParsing() =
124146
let results = checker.ParseFile("TypeChecker.fs", source.ToFSharpSourceText(), parsingOptions) |> Async.RunSynchronously
125147
if results.ParseHadErrors then failwithf "parse had errors: %A" results.Errors
126148

149+
[<IterationSetup(Target = "ILReading")>]
150+
member __.ILReadingSetup() =
151+
// With caching, performance increases an order of magnitude when re-reading an ILModuleReader.
152+
// Clear it for benchmarking.
153+
ClearAllILModuleReaderCache()
154+
155+
[<Benchmark>]
156+
member __.ILReading() =
157+
match assembliesOpt with
158+
| None -> failwith "no assemblies"
159+
| Some(assemblies) ->
160+
// We try to read most of everything in the assembly that matter, mainly types with their properties, methods, and fields.
161+
// CustomAttrs and SecurityDecls are lazy until you call them, so we call them here for benchmarking.
162+
assemblies
163+
|> Array.iter (fun (fileName) ->
164+
let reader = OpenILModuleReader fileName readerOptions
165+
166+
let ilModuleDef = reader.ILModuleDef
167+
168+
let ilAssemblyManifest = ilModuleDef.Manifest.Value
169+
170+
ilAssemblyManifest.CustomAttrs |> ignore
171+
ilAssemblyManifest.SecurityDecls |> ignore
172+
ilAssemblyManifest.ExportedTypes.AsList
173+
|> List.iter (fun x ->
174+
x.CustomAttrs |> ignore
175+
)
176+
177+
ilModuleDef.CustomAttrs |> ignore
178+
ilModuleDef.TypeDefs.AsArray
179+
|> Array.iter (fun ilTypeDef ->
180+
ilTypeDef.CustomAttrs |> ignore
181+
ilTypeDef.SecurityDecls |> ignore
182+
183+
ilTypeDef.Methods.AsArray
184+
|> Array.iter (fun ilMethodDef ->
185+
ilMethodDef.CustomAttrs |> ignore
186+
ilMethodDef.SecurityDecls |> ignore
187+
)
188+
189+
ilTypeDef.Fields.AsList
190+
|> List.iter (fun ilFieldDef ->
191+
ilFieldDef.CustomAttrs |> ignore
192+
)
193+
194+
ilTypeDef.Properties.AsList
195+
|> List.iter (fun ilPropertyDef ->
196+
ilPropertyDef.CustomAttrs |> ignore
197+
)
198+
)
199+
)
200+
127201
[<EntryPoint>]
128202
let main argv =
129-
let _ = BenchmarkRunner.Run<CompilerServiceParsing>()
130-
0
203+
let _ = BenchmarkRunner.Run<CompilerService>()
204+
0

benchmarks/Directory.Build.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Project>
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove('FSharp.Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
3+
</Project>

benchmarks/Directory.Build.targets

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Project>
2+
<Import Project="$([MSBuild]::GetPathOfFileAbove('FSharp.Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))" />
3+
</Project>

src/absil/ilread.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4002,6 +4002,8 @@ let OpenILModuleReaderFromBytes fileName bytes opts =
40024002
let ilModule, ilAssemblyRefs, pdb = openPE (fileName, pefile, opts.pdbDirPath, (opts.reduceMemoryUsage = ReduceMemoryFlag.Yes), opts.ilGlobals, true)
40034003
new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) :> ILModuleReader
40044004

4005+
let ClearAllILModuleReaderCache() = ilModuleReaderCache.Clear(ILModuleReaderCacheLockToken())
4006+
40054007
let OpenILModuleReader fileName opts =
40064008
// Pseudo-normalize the paths.
40074009
let (ILModuleReaderCacheKey (fullPath,writeStamp,_,_,_,_) as key), keyOk =

src/absil/ilread.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ type ILModuleReader =
8080
/// PDB files may not be read with this option.
8181
val internal OpenILModuleReader: string -> ILReaderOptions -> ILModuleReader
8282

83+
val internal ClearAllILModuleReaderCache : unit -> unit
84+
8385
/// Open a binary reader based on the given bytes.
8486
val internal OpenILModuleReaderFromBytes: fileNameForDebugOutput:string -> assemblyContents: byte[] -> options: ILReaderOptions -> ILModuleReader
8587

src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
<InternalsVisibleTo Include="HostedCompilerServer" />
6060
<InternalsVisibleTo Include="FSharp.Tests.FSharpSuite" />
6161
<InternalsVisibleTo Include="LanguageServiceProfiling" />
62+
<InternalsVisibleTo Include="CompilerServiceBenchmarks" />
6263
</ItemGroup>
6364

6465
<ItemGroup>

0 commit comments

Comments
 (0)