提交 acbca82a 编写于 作者: S Steffen Forkmann 提交者: Kevin Ransom (msft)

Reduce allocations by favoring TryGetValue over TryFind (#5715)

* Remove old TryGetValue

* Reduce use of TryFind

* Reduce allocations in TcPatBindingName

* Reduce some allocations in NameResolution

* Reduce some allocations in TypeChecker

* Use latest FSharp.Core in FCS

* Update FSharp.Core in FCS
上级 51e89fc9
......@@ -1123,7 +1123,7 @@ module NameMap =
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module NameMultiMap =
let existsInRange f (m: NameMultiMap<'T>) = NameMap.exists (fun _ l -> List.exists f l) m
let find v (m: NameMultiMap<'T>) = match Map.tryFind v m with None -> [] | Some r -> r
let find v (m: NameMultiMap<'T>) = match m.TryGetValue v with true, r -> r | _ -> []
let add v x (m: NameMultiMap<'T>) = NameMap.add v (x :: find v m) m
let range (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> x @ sofar) m []
let rangeReversingEachBucket (m: NameMultiMap<'T>) = Map.foldBack (fun _ x sofar -> List.rev x @ sofar) m []
......@@ -1137,7 +1137,7 @@ module NameMultiMap =
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module MultiMap =
let existsInRange f (m: MultiMap<_,_>) = Map.exists (fun _ l -> List.exists f l) m
let find v (m: MultiMap<_,_>) = match Map.tryFind v m with None -> [] | Some r -> r
let find v (m: MultiMap<_,_>) = match m.TryGetValue v with true, r -> r | _ -> []
let add v x (m: MultiMap<_,_>) = Map.add v (x :: find v m) m
let range (m: MultiMap<_,_>) = Map.foldBack (fun _ x sofar -> x @ sofar) m []
let empty : MultiMap<_,_> = Map.empty
......@@ -1148,11 +1148,6 @@ type LayeredMap<'Key,'Value when 'Key : comparison> = Map<'Key,'Value>
type Map<'Key,'Value when 'Key : comparison> with
static member Empty : Map<'Key,'Value> = Map.empty
member m.TryGetValue (key,res:byref<'Value>) =
match m.TryFind key with
| None -> false
| Some r -> res <- r; true
member x.Values = [ for (KeyValue(_,v)) in x -> v ]
member x.AddAndMarkAsCollapsible (kvs: _[]) = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v))
member x.LinearTryModifyThenLaterFlatten (key, f: 'Value option -> 'Value) = x.Add (key, f (x.TryFind key))
......@@ -1162,12 +1157,13 @@ type Map<'Key,'Value when 'Key : comparison> with
[<Sealed>]
type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(contents : LayeredMap<'Key,'Value list>) =
member x.Add (k,v) = LayeredMultiMap(contents.Add(k,v :: x.[k]))
member x.Item with get k = match contents.TryFind k with None -> [] | Some l -> l
member x.Item with get k = match contents.TryGetValue k with true, l -> l | _ -> []
member x.AddAndMarkAsCollapsible (kvs: _[]) =
let x = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v))
x.MarkAsCollapsible()
member x.MarkAsCollapsible() = LayeredMultiMap(contents.MarkAsCollapsible())
member x.TryFind k = contents.TryFind k
member x.TryGetValue k = contents.TryGetValue k
member x.Values = contents.Values |> List.concat
static member Empty : LayeredMultiMap<'Key,'Value> = LayeredMultiMap LayeredMap.Empty
......
此差异已折叠。
......@@ -166,9 +166,6 @@ type FullyQualifiedFlag =
[<RequireQualifiedAccess>]
type BulkAdd = Yes | No
/// Lookup patterns in name resolution environment
val internal TryFindPatternByName : string -> NameResolutionEnv -> Item option
/// Add extra items to the environment for Visual Studio, e.g. static members
val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv
......
......@@ -4470,9 +4470,9 @@ and TcTyparOrMeasurePar optKind cenv (env:TcEnv) newOk tpenv (Typar(id, _, _) as
// CallNameResolutionSink cenv.tcSink (tp.Range.StartRange, env.NameEnv, item, item, ItemOccurence.UseInType, env.DisplayEnv, env.eAccessRights)
res, tpenv
let key = id.idText
match env.eNameResEnv.eTypars.TryFind key with
| Some res -> checkRes res
| None ->
match env.eNameResEnv.eTypars.TryGetValue key with
| true, res -> checkRes res
| _ ->
match TryFindUnscopedTypar key tpenv with
| Some res -> checkRes res
| None ->
......@@ -5101,17 +5101,17 @@ and TcPatBindingName cenv env id ty isMemberThis vis1 topValData (inlineFlag, de
let names = Map.add id.idText (PrelimValScheme1(id, declaredTypars, ty, topValData, None, isMutable, inlineFlag, baseOrThis, argAttribs, vis, compgen)) names
let takenNames = Set.add id.idText takenNames
(fun (TcPatPhase2Input (values, isLeftMost)) ->
let (vspec, typeScheme) =
match values.TryFind id.idText with
| Some value ->
let name = id.idText
let (vspec, typeScheme) =
let name = id.idText
match values.TryGetValue name with
| true, value ->
if not (String.IsNullOrEmpty name) && Char.IsLower(name.[0]) then
match TryFindPatternByName name env.eNameResEnv with
| Some (Item.Value vref) when vref.LiteralValue.IsSome ->
warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern(id.idText), id.idRange))
| Some _ | None -> ()
match env.eNameResEnv.ePatItems.TryGetValue name with
| true, Item.Value vref when vref.LiteralValue.IsSome ->
warning(Error(FSComp.SR.checkLowercaseLiteralBindingInPattern name, id.idRange))
| _ -> ()
value
| None -> error(Error(FSComp.SR.tcNameNotBoundInPattern(id.idText), id.idRange))
| _ -> error(Error(FSComp.SR.tcNameNotBoundInPattern name, id.idRange))
// isLeftMost indicates we are processing the left-most path through a disjunctive or pattern.
// For those binding locations, CallNameResolutionSink is called in MakeAndPublishValue, like all other bindings
......@@ -5198,10 +5198,10 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p
// matching
error (UnionPatternsBindDifferentNames m)
names1 |> Map.iter (fun _ (PrelimValScheme1(id1, _, ty1, _, _, _, _, _, _, _, _)) ->
match Map.tryFind id1.idText names2 with
| None -> ()
| Some (PrelimValScheme1(_, _, ty2, _, _, _, _, _, _, _, _)) ->
UnifyTypes cenv env m ty1 ty2)
match names2.TryGetValue id1.idText with
| true, PrelimValScheme1(_, _, ty2, _, _, _, _, _, _, _, _) ->
UnifyTypes cenv env m ty1 ty2
| _ -> ())
(fun values -> TPat_disjs ([pat1' values;pat2' values.RightPath], m)), (tpenv, names1, takenNames1)
| SynPat.Ands (pats, m) ->
......@@ -5442,9 +5442,9 @@ and TcPat warnOnUpper cenv env topValInfo vFlags (tpenv, names, takenNames) ty p
let ftys = fields |> List.map (fun fsp -> actualTyOfRecdField inst fsp, fsp)
let fldsmap', acc =
((tpenv, names, takenNames), ftys) ||> List.mapFold (fun s (ty, fsp) ->
match Map.tryFind fsp.rfield_id.idText fldsmap with
| Some v -> TcPat warnOnUpper cenv env None vFlags s ty v
| None -> (fun _ -> TPat_wild m), s)
match fldsmap.TryGetValue fsp.rfield_id.idText with
| true, v -> TcPat warnOnUpper cenv env None vFlags s ty v
| _ -> (fun _ -> TPat_wild m), s)
(fun values -> TPat_recd (tcref, tinst, List.map (fun f -> f values) fldsmap', m)),
acc
......@@ -11598,10 +11598,10 @@ and TcIncrementalLetRecGeneralization cenv scopem
// pathological situations
let freeInUncheckedRecBinds =
lazy ((emptyFreeTyvars, cenv.recUses.Contents) ||> Map.fold (fun acc vStamp _ ->
match Map.tryFind vStamp uncheckedRecBindsTable with
| Some fwdBind ->
accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc
| None ->
match uncheckedRecBindsTable.TryGetValue vStamp with
| true, fwdBind ->
accFreeInType CollectAllNoCaching fwdBind.RecBindingInfo.Val.Type acc
| _ ->
acc))
let rec loop (preGeneralizationRecBinds: PreGeneralizationRecursiveBinding list,
......@@ -16024,12 +16024,12 @@ module TcDeclarations =
else
let isInSameModuleOrNamespace =
match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryFind(tcref.LogicalName) with
| Some tycon -> (tyconOrder.Compare(tcref.Deref, tycon) = 0)
| None ->
match envForDecls.eModuleOrNamespaceTypeAccumulator.Value.TypesByMangledName.TryGetValue tcref.LogicalName with
| true, tycon -> tyconOrder.Compare(tcref.Deref, tycon) = 0
| _ ->
//false
// There is a special case we allow when compiling FSharp.Core.dll which permits interface implementations across namespace fragments
(cenv.g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`"))
cenv.g.compilingFslib && tcref.LogicalName.StartsWithOrdinal("Tuple`")
let nReqTypars = reqTypars.Length
......
......@@ -3046,13 +3046,12 @@ and
static member TryDerefEntityPath(ccu: CcuThunk, path:string[], i:int, entity:Entity) =
if i >= path.Length then ValueSome entity
else
let next = entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind(path.[i])
match next with
| Some res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res)
match entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryGetValue path.[i] with
| true, res -> NonLocalEntityRef.TryDerefEntityPath(ccu, path, (i+1), res)
#if !NO_EXTENSIONTYPING
| None -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity)
| _ -> NonLocalEntityRef.TryDerefEntityPathViaProvidedType(ccu, path, i, entity)
#else
| None -> ValueNone
| _ -> ValueNone
#endif
#if !NO_EXTENSIONTYPING
......@@ -4199,9 +4198,10 @@ and
/// Try to resolve a path into the CCU by referencing the .NET/CLI type forwarder table of the CCU
member ccu.TryForward(nlpath:string[],item:string) : EntityRef option =
ccu.EnsureDerefable(nlpath)
match ccu.TypeForwarders.TryFind(nlpath,item) with
| Some entity -> Some(entity.Force())
| None -> None
let key = nlpath,item
match ccu.TypeForwarders.TryGetValue key with
| true, entity -> Some(entity.Force())
| _ -> None
//printfn "trying to forward %A::%s from ccu '%s', res = '%A'" p n ccu.AssemblyName res.IsSome
/// Used to make forward calls into the type/assembly loader when comparing member signatures during linking
......@@ -5719,13 +5719,13 @@ let CombineCcuContentFragments m l =
let tab2 = mty2.AllEntitiesByLogicalMangledName
let entities =
[ for e1 in mty1.AllEntities do
match tab2.TryFind e1.LogicalName with
| Some e2 -> yield CombineEntites path e1 e2
| None -> yield e1
match tab2.TryGetValue e1.LogicalName with
| true, e2 -> yield CombineEntites path e1 e2
| _ -> yield e1
for e2 in mty2.AllEntities do
match tab1.TryFind e2.LogicalName with
| Some _ -> ()
| None -> yield e2 ]
match tab1.TryGetValue e2.LogicalName with
| true, _ -> ()
| _ -> yield e2 ]
let vals = QueueList.append mty1.AllValsAndMembers mty2.AllValsAndMembers
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册