11
votes

Pourquoi utiliser gethashcode () sur des égaux ()?

hashset .add compare d'abord les résultats de gethashcode . Si ceux-ci sont égaux, il appelle égale .

Maintenant, ma compréhension est de mettre en place gethascode , quelque chose doit être fait avec les champs d'un objet. Un exemple simple implémentation peut être trouvé sur Quel est le meilleur algorithme pour un système remplacé.Object.GetHashCode? .

Dans mon test comparant à la fois sur 1.000.000 paires d'objets remplis de données aléatoires, les performances sont plus ou moins égales entre les deux. gethashcode est implémenté comme dans l'exemple lié, est égal à simplement appelle est égal à sur tous les champs. Alors, pourquoi voudrait-on utiliser gethascode sur est égal à ?


2 commentaires

Pour un objet important avec de nombreux champs réadonnants, le code de hachage peut être calculé dans le constructeur et stocké sous forme de champ supplémentaire de l'objet. Dans ce cas, la méthode Equals utiliserait le champ de code de hachage comme optimisation avant de comparer les autres valeurs de champ. Si le code de hachage est différent, nous pouvons être certains que les champs restants sont également différents. Cela fonctionne si utilisé dans une table de hachage ou simplement utilisé dans des comparaisons d'égalité. GetHashCode renvoie le champ de code de hachage pré-calculé. Si certains champs sont également des objets immuables, cela peut réduire de nombreux niveaux et accélérer les comparaisons.


+1 pour une bonne question. Ceci est une bonne variante de questions similaires infinies sur le sujet de gethashcode sur donc.


5 Réponses :


1
votes

gethashcode () Vous fait une valeur intégrale que vous pouvez utiliser pour les hashtables. Ce code de hachage est une raison pour laquelle les hachables sont si performants. Cependant, il peut y avoir plus d'un objet avec le même hashcode. C'est pourquoi est égal () est appelé. Si les objets ne sont pas égaux, ils peuvent entrer dans le même seau, s'ils sont égaux, il est déjà dans la hache et n'a pas besoin d'être ajouté.


0 commentaires

2
votes

gethashcode vous permet de mettre une chose dans des seaux - plusieurs objets peuvent avoir le même code de hachage. Equals est ensuite utilisé pour trouver des allumettes dans un seau. Cela vous permet de trouver des choses dans de grandes collections très rapidement


1 commentaires

très bonne réponse :-). simple et le meilleur



8
votes

Parce que si un algorithme veut tester si 1 objet est déjà dans un ensemble d'objets 1.000.000, il doit appeler égale 1.000.000 fois, mais gethashcode () juste une fois (et quelques appels vers égale pour éliminer les objets qui sont différents, bien qu'avoir le même code de hachage).


0 commentaires

20
votes

Pour certains types, un test est égal à peut être relativement coûteux. Il doit généralement comparer chaque domaine de la classe. En d'autres termes, il faut du temps linéaire de la taille de la classe. Les classes plus grandes sont plus chères à comparer pour l'égalité.

Maintenant, que se passe-t-il si vous devez avoir besoin de comparer un objet contre 1000 autres? Appeler est égal à 1000 fois pourrait coûter cher. Vous devez faire des accès au champ N * 2000, si N est la taille de la classe

gethashcode génère plutôt un entiteur "principalement unique" basé sur le contenu de la classe. En d'autres termes, les champs de classe sont accessibles une fois . Et une fois que vous avez cela, vous pouvez comparer cet entier aux 1000 entiers qui constituent les codes de hachage des autres objets.

Même dans un tel cas d'utilisation naïf, nous n'avons maintenant besoin que de N * 1000 Accesses de champ.

Mais si nous stocker le code de hachage? Lorsque nous insérons un objet dans un jeu de hachage, son code de hachage est calculé une fois . Maintenant, tout temps Nous voulons faire une recherche dans le jeu de hachage, il suffit de calculer un code de hachage (celui de l'objet externe), puis vous avez juste comparer des entiers simples. Donc, n Accesses de champ de classe (pour le nouvel objet dont nous devons calculer le code de hachage), ainsi qu'un certain nombre de comparaisons entier, qui varient, en fonction de l'algorithme, mais sont 1) relativement peu, et 2) pas cher.


4 commentaires

Je n'avais pas pensé à la possibilité de stocker le hachage. Explication claire.


@Stijn: En réalité, les tables de hachage sont très complexes que cela, mais oui, l'idée de base est d'éviter de recomputer le hachage


En réalité, vous devez faire un accès de champ N * 2 * 1000 uniquement si tous les objets 1001 sont égaux; Obtenir le code de hachage, inversement, sûrement frappe tous les champs dans chaque objet. En fin de compte, vous gagnez un facteur 2 WRT aux comparaisons de champ dans le pire des cas, perdant un peu de temps pour obtenir ces hachages.


Ne pas oublier que si est égal à est cher, c'est équivalent exact gethashcode sera également ou plus cher. L'avantage réel commence lorsque vous ne le calculez qu'une seule fois. Bon point +1.



1
votes

L'aspect essentiel de gethascode est-ce une observation que deux objets de hashcodes de deux objets diffèrent non seulement une observation que les objets sont différents, mais une observation de quelque chose de beaucoup plus puissant: si les hashcodes de tous Les articles d'un ensemble ont une propriété manquante de celles de tous les objets d'une autre, puis les ensembles n'ont aucun objet en commun.

Par exemple, si on met en un ensemble, tous les objets où gethascode renvoie un nombre pair, et dans un ensemble différent Tous les objets où gethascode renvoie un nombre impair, puis On a ensuite donné un objet à rechercher, appelant gethascode permettra d'éliminer instantanément de considérer tous les objets de l'un des ensembles. Si au lieu d'utiliser deux ensembles, on utilise vingt, on pourrait tout éliminer de dix-neuf ensembles. Si 256 sets, on peut éliminer 255. Dans de nombreux cas, si l'on ajuste le nombre d'ensembles en fonction du nombre d'éléments, il sera possible d'éliminer toutes sauf une poignée d'objets sans avoir à regarder aucun d'entre eux.

REGARDER LES HASHCODES DE DEUX OBJETS POUR VOIR S'ils peuvent être égaux seront rarement plus rapides que de vérifier simplement les objets directement pour l'égalité. D'autre part, être capable de savoir qu'un objet n'est pas égal à 999 990 autres sans les regarder, il est susceptible d'être beaucoup plus rapide que de regarder la comparaison de l'égalité autrement.


0 commentaires