Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 0893287

Browse files
authored
Mitigate some of #495 via MRO member selection and analysis set optimization (#517)
This isn't a complete fix, but does seem to improve #495 in some cases. Adds back the early MRO return removed in #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 cb1c3df commit 0893287

File tree

7 files changed

+37
-14
lines changed

7 files changed

+37
-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
@@ -206,7 +206,7 @@ public async Task Handler(CancellationToken cancellationToken) {
206206
}
207207

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

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

src/Analysis/Engine/Impl/LocationInfo.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,13 @@ 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() { }
92+
8993
public bool Equals(LocationInfo x, LocationInfo y) => Equals(x, y);
9094
public bool Equals(ILocationInfo x, ILocationInfo y) {
9195
return x.StartLine == y.StartLine &&

src/Analysis/Engine/Impl/OverloadResult.cs

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

427427
class OverloadResultComparer : EqualityComparer<OverloadResult> {
428-
public static IEqualityComparer<OverloadResult> Instance = new OverloadResultComparer(false);
429-
public static IEqualityComparer<OverloadResult> WeakInstance = new OverloadResultComparer(true);
428+
public static readonly IEqualityComparer<OverloadResult> Instance = new OverloadResultComparer(false);
429+
public static readonly IEqualityComparer<OverloadResult> WeakInstance = new OverloadResultComparer(true);
430430

431431
private readonly bool _weak;
432432

src/Analysis/Engine/Impl/PythonAnalyzer.cs

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

923923
class AggregateComparer : IEqualityComparer<IProjectEntry[]> {
924-
public static AggregateComparer Instance = new AggregateComparer();
924+
public static readonly AggregateComparer Instance = new AggregateComparer();
925+
926+
private AggregateComparer() { }
925927

926928
public bool Equals(IProjectEntry[] x, IProjectEntry[] y) {
927929
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)