2016-06-09 12 views
3

Ich habe eine Klasse geschrieben, die von IEqualityComparer<T> abgeleitet ist, die für die LINQ-Abfrage funktioniert, für die ich sie brauchte.Verwenden des GetHashCode() - Teils von IEqualityComparer <T> für direkte Vergleiche?

Wie ich es verstehe, GetHashCode() (schnell) wird zuerst genannt, dann Equals() (etwas langsamer), wenn der Hashcode der gleiche ist, für solche Operationen.

jedoch, wenn es für einen direkten Vergleich mit manuell, ich bin mit so etwas wie

return new MyIEqualityComparer().Equals(objA,objB); 

, die die schnellere GetHashCode() Gleichheitsprüfung verzichtet. Gibt es eine Möglichkeit, objA mit objB zu vergleichen, die nicht automatisch die schnellere Prüfung GetHashCode() überspringen?

Ich glaube, ich hatte gehofft objA.Equals() würde eine Überladung haben, die ein Argument von IEqualityComparer<T> abgeleitet akzeptiert.

+1

Haben Sie ein Leistungsproblem, das Sie zu lösen versuchen, oder ist das nur "Optimierung"? – stuartd

+0

GetHashCode stellt keine Gleichheit her, es lässt Sie herausfinden, zu welchem ​​Bucket ein Element in einer Hash-Tabelle gehört (Dictionary oder HashSet), so dass es eine tatsächliche Gleichheitsprüfung für viel weniger Elemente als die gesamte Sammlung durchführen kann. –

+0

Sein Hauptzweck ist es, Objekte in eine Hash-Tabelle zu setzen, ich glaube nicht, dass Sie irgendwelche Garantien dafür nehmen können, ob es schneller ist oder nicht. –

Antwort

0

Es ist nicht wirklich klar, was du bist hier bis zu, aber man kann immer IEquatable<T> implementieren und zu MyIEqualityComparer delegieren, damit schneller GetHashCode() mit:

class My : IEquatable<My> 
{ 
    public bool Equals(My other) 
    { 
     return new MyIEqualityComparer().Equals(this, other); 
    } 
} 
2

Computing einen Hash-Code und den Vergleich der Hash-Regel langsamer ist als direkt für die Gleichheit zu vergleichen. Es ist zusätzliche Arbeit.

Hash-Codes unterstützen das O(1) Verhalten von Hash-Tabellen. Sie ordnen ein Objekt einer Nummer zu, die für Hash-Tabellen erforderlich ist. Hash-Codes sind nicht hilfreich für bloße Gleichheitsvergleiche.

Verwenden Sie einfach Equals.

Wenn Sie wissen möchten, wie Sie Ihre Idee umzusetzen (obwohl es keine gute Idee ist) ich eine Hilfsmethode verwenden würde: (. Nur für Bildungszwecke)

static bool ExperimentalEquals<T>(T a, T b, IEqualityComparer<T> c) { 
if (c.GetHashCode(a) != c.GetHashCode(b)) return false; 
return c.Equals(a, b); 
} 

Sie könnten denken, dass im Falle eines zwischengespeicherten Hash-Codes dies tatsächlich schneller sein könnte. Aber dann könnte Equals den Cache-Hash-Code selbst verwenden und den Vergleich kurzschließen.