Skip to content

Commit 44dec43

Browse files
committed
Minor perf opt:
- isNull is inline also in FSharp.Core - Faster eqTypes - Lazy load of ILAssemblyRefs - Avoid looping 120 libraries through on most cases
1 parent 23b588d commit 44dec43

File tree

1 file changed

+35
-25
lines changed

1 file changed

+35
-25
lines changed

src/ProvidedTypes.fs

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ open Microsoft.FSharp.Core.CompilerServices
2424
[<AutoOpen>]
2525
module Utils =
2626
let K x = (fun () -> x)
27-
let isNull x = match x with null -> true | _ -> false
28-
let isNil x = match x with [] -> true | _ -> false
29-
let isEmpty x = match x with [| |] -> true | _ -> false
27+
let inline isNull x = match x with null -> true | _ -> false
28+
let inline isNil x = match x with [] -> true | _ -> false
29+
let inline isEmpty x = match x with [| |] -> true | _ -> false
3030

3131
module Option =
3232
let toObj x = match x with None -> null | Some x -> x
@@ -81,7 +81,7 @@ module Utils =
8181
elif ty1.IsArray then ty2.IsArray && ty1.GetArrayRank() = ty2.GetArrayRank() && eqTypes (ty1.GetElementType()) (ty2.GetElementType())
8282
elif ty1.IsPointer then ty2.IsPointer && eqTypes (ty1.GetElementType()) (ty2.GetElementType())
8383
elif ty1.IsByRef then ty2.IsByRef && eqTypes (ty1.GetElementType()) (ty2.GetElementType())
84-
else ty1.Equals(box ty2)
84+
else Type.(=)(ty1, ty2)
8585

8686
/// General implementation of .Equals(obj) logic for System.Type over symbol types. You can use this with other types too.
8787
let eqTypeObj (this: Type) (other: obj) =
@@ -6253,11 +6253,10 @@ module internal AssemblyReader =
62536253

62546254

62556255
let ilModule = seekReadModule (ilMetadataVersion) 1
6256-
let ilAssemblyRefs = [ for i in 1 .. getNumRows ILTableNames.AssemblyRef do yield seekReadAssemblyRef i ]
62576256

62586257
member __.ILGlobals = ilg
62596258
member __.ILModuleDef = ilModule
6260-
member __.ILAssemblyRefs = ilAssemblyRefs
6259+
member __.ILAssemblyRefs = lazy [ for i in 1 .. getNumRows ILTableNames.AssemblyRef do yield seekReadAssemblyRef i ]
62616260

62626261
let sigptr_get_byte (bytes: byte[]) sigptr =
62636262
int bytes.[sigptr], sigptr + 1
@@ -8131,7 +8130,7 @@ namespace ProviderImplementation.ProvidedTypes
81318130
let types = lazy [| for td in getReader().ILModuleDef.TypeDefs.Entries -> txILTypeDef None td |]
81328131

81338132

8134-
override __.GetReferencedAssemblies() = [| for aref in getReader().ILAssemblyRefs -> aref.ToAssemblyName() |]
8133+
override __.GetReferencedAssemblies() = [| for aref in getReader().ILAssemblyRefs.Force() -> aref.ToAssemblyName() |]
81358134

81368135
override __.GetTypes () = types.Force()
81378136

@@ -9120,31 +9119,42 @@ namespace ProviderImplementation.ProvidedTypes
91209119
let asms = (if toTgt then getTargetAssemblies() else getSourceAssemblies())
91219120
let fullName = fixName t.FullName
91229121

9123-
// TODO: this linear search through all available source/target assemblies feels as if it must be too slow in some cases.
9124-
// However, we store type translations in various tables (typeTableFwd and typeTableBwd) so perhaps it is not a problem
9125-
let rec loop i =
9126-
if i < 0 then
9127-
let msg =
9128-
if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList)
9129-
elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occured while determining compilation references"
9130-
else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList)
9131-
failwith msg
9132-
else
9133-
match tryGetTypeFromAssembly toTgt t.Assembly.FullName fullName asms.[i] with
9134-
| Some (newT, canSave) ->
9135-
if canSave then table.[t] <- newT
9136-
newT
9137-
| None -> loop (i - 1)
9138-
loop (asms.Count - 1)
9122+
let bestGuess =
9123+
asms |> Seq.tryFind(fun a -> a.FullName = t.Assembly.FullName)
9124+
|> Option.bind(fun a -> tryGetTypeFromAssembly toTgt t.Assembly.FullName fullName a)
9125+
9126+
match bestGuess with
9127+
| Some (newT, canSave) ->
9128+
if canSave then table.[t] <- newT
9129+
newT
9130+
| None ->
9131+
9132+
// TODO: this linear search through all available source/target assemblies feels as if it must be too slow in some cases.
9133+
// However, we store type translations in various tables (typeTableFwd and typeTableBwd) so perhaps it is not a problem
9134+
let rec loop i =
9135+
if i < 0 then
9136+
let msg =
9137+
if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList)
9138+
elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occured while determining compilation references"
9139+
else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList)
9140+
failwith msg
9141+
else
9142+
match tryGetTypeFromAssembly toTgt t.Assembly.FullName fullName asms.[i] with
9143+
| Some (newT, canSave) ->
9144+
if canSave then table.[t] <- newT
9145+
newT
9146+
| None -> loop (i - 1)
9147+
loop (asms.Count - 1)
91399148

91409149
and convType toTgt (t:Type) =
91419150
let table = (if toTgt then typeTableFwd else typeTableBwd)
91429151
match table.TryGetValue(t) with
91439152
| true, newT -> newT
91449153
| false, _ ->
9145-
if t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpTypeAbbreviation then t
9154+
let isSymbol = t :? ProvidedTypeSymbol
9155+
if isSymbol && (t :?> ProvidedTypeSymbol).IsFSharpTypeAbbreviation then t
91469156
// Types annotated with units-of-measure
9147-
elif t :? ProvidedTypeSymbol && (t :?> ProvidedTypeSymbol).IsFSharpUnitAnnotated then
9157+
elif isSymbol && (t :?> ProvidedTypeSymbol).IsFSharpUnitAnnotated then
91489158
let genericType = t.GetGenericTypeDefinition()
91499159
let newT = convTypeRef toTgt genericType
91509160
let typeArguments = t.GetGenericArguments() |> Array.map (convType toTgt) |> Array.toList

0 commit comments

Comments
 (0)