Skip to content

Commit 3026694

Browse files
jakebaileyAlexanderSher
authored andcommitted
Mitigate some of microsoft#495 via MRO member selection and analysis set optimization (microsoft#517)
This isn't a complete fix, but does seem to improve microsoft#495 in some cases. Adds back the early MRO return removed in microsoft#277, so now large class hierarchies won't over-propagate types (where some of the trouble with fastai happens do to the Transform class). I also optimized AnalysisHashSet a little to do length checks when possible. There are still times when things get caught up comparing unions for a while, but it seems to be nondeterministic.
1 parent dde837b commit 3026694

File tree

7 files changed

+36
-14
lines changed

7 files changed

+36
-14
lines changed

src/Analysis/Engine/Impl/AnalysisHashSet.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,19 @@ public bool SetEquals(IAnalysisSet other) {
275275
return true;
276276
}
277277

278+
// Only access Count once to prevent wasted time in bucket locks.
279+
var lCount = Count;
280+
var rCount = other.Count;
281+
282+
if (lCount == 0 && rCount == 0) {
283+
return true;
284+
}
285+
278286
if (Comparer == other.Comparer) {
287+
if (lCount != rCount) {
288+
return false;
289+
}
290+
279291
// Quick check for any unmatched hashcodes.
280292
// This can conclusively prove the sets are not equal, but cannot
281293
// prove equality.
@@ -290,17 +302,16 @@ public bool SetEquals(IAnalysisSet other) {
290302
}
291303
}
292304

293-
var otherHc = new HashSet<AnalysisValue>(other, _comparer);
294-
foreach (var key in this) {
295-
if (!otherHc.Remove(key)) {
296-
return false;
297-
}
298-
}
299-
if (otherHc.Any()) {
305+
if (lCount == 0 || rCount == 0) {
300306
return false;
301307
}
302308

303-
return true;
309+
if (lCount == 1 && rCount == 1) {
310+
return _comparer.Equals(this.First(), other.First());
311+
}
312+
313+
var hs = new HashSet<AnalysisValue>(other, _comparer);
314+
return hs.SetEquals(this);
304315
}
305316

306317
/// <summary>

src/Analysis/Engine/Impl/AnalysisSet.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,8 @@ public static bool ContainsAny(this IAnalysisSet set, IAnalysisSet values) {
534534
sealed class ObjectComparer : IEqualityComparer<AnalysisValue>, IEqualityComparer<IAnalysisSet> {
535535
public static readonly ObjectComparer Instance = new ObjectComparer();
536536

537+
private ObjectComparer() { }
538+
537539
public bool Equals(AnalysisValue x, AnalysisValue y) {
538540
#if FULL_VALIDATION
539541
if (x != null && y != null) {
@@ -574,7 +576,7 @@ sealed class UnionComparer : IEqualityComparer<AnalysisValue>, IEqualityComparer
574576

575577
public readonly int Strength;
576578

577-
public UnionComparer(int strength = 0) {
579+
private UnionComparer(int strength = 0) {
578580
Strength = strength;
579581
}
580582

src/Analysis/Engine/Impl/Intellisense/AnalysisQueue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public async Task Handler(CancellationToken cancellationToken) {
208208
}
209209

210210
private sealed class QueueItemComparer : IEqualityComparer<QueueItem> {
211-
public static IEqualityComparer<QueueItem> Instance { get; } = new QueueItemComparer();
211+
public static readonly IEqualityComparer<QueueItem> Instance = new QueueItemComparer();
212212

213213
private QueueItemComparer() { }
214214
public bool Equals(QueueItem x, QueueItem y) => Equals(x.Key, y.Key);

src/Analysis/Engine/Impl/LocationInfo.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,12 @@ public bool Equals(ILocationInfo other) {
8383
/// Provides an IEqualityComparer that compares line, column and project entries. By
8484
/// default locations are equaitable based upon only line/project entry.
8585
/// </summary>
86-
public static IEqualityComparer<ILocationInfo> FullComparer { get; } = new FullLocationComparer();
86+
public static IEqualityComparer<ILocationInfo> FullComparer => FullLocationComparer.Instance;
8787

8888
sealed class FullLocationComparer : IEqualityComparer<ILocationInfo>, IEqualityComparer<LocationInfo> {
89+
public static readonly FullLocationComparer Instance = new FullLocationComparer();
90+
91+
private FullLocationComparer() { }
8992
public bool Equals(LocationInfo x, LocationInfo y) => EqualsImpl(x, y);
9093
public bool Equals(ILocationInfo x, ILocationInfo y) => EqualsImpl(x, y);
9194

src/Analysis/Engine/Impl/OverloadResult.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ internal ParameterResult GetParameterResultFromParameterInfo(IParameterInfo para
411411
}
412412

413413
class OverloadResultComparer : EqualityComparer<OverloadResult> {
414-
public static IEqualityComparer<OverloadResult> Instance = new OverloadResultComparer(false);
415-
public static IEqualityComparer<OverloadResult> WeakInstance = new OverloadResultComparer(true);
414+
public static readonly IEqualityComparer<OverloadResult> Instance = new OverloadResultComparer(false);
415+
public static readonly IEqualityComparer<OverloadResult> WeakInstance = new OverloadResultComparer(true);
416416

417417
private readonly bool _weak;
418418

src/Analysis/Engine/Impl/PythonAnalyzer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,9 @@ private AggregateProjectEntry GetAggregateWorker(IProjectEntry[] all) {
904904
}
905905

906906
class AggregateComparer : IEqualityComparer<IProjectEntry[]> {
907-
public static AggregateComparer Instance = new AggregateComparer();
907+
public static readonly AggregateComparer Instance = new AggregateComparer();
908+
909+
private AggregateComparer() { }
908910

909911
public bool Equals(IProjectEntry[] x, IProjectEntry[] y) {
910912
if (x.Length != y.Length) {

src/Analysis/Engine/Impl/Values/ClassInfo.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,10 @@ public static IAnalysisSet GetMemberFromMroNoReferences(IEnumerable<IAnalysisSet
831831
result = result.Union(ns.GetMember(node, unit, name));
832832
}
833833
}
834+
835+
if (result != null && result.Count > 0) {
836+
break;
837+
}
834838
}
835839
return result;
836840
}

0 commit comments

Comments
 (0)