J'avais l'habitude d'utiliser le constructeur Apache HashCode beaucoup P>
Est-ce qu'il existe pour C # P>
5 Réponses :
J'utilise ce qui suit:
public static int ComputeHashFrom(params object[] obj) {
ulong res = 0;
for(uint i=0;i<obj.Length;i++) {
object val = obj[i];
res += val == null ? i : (ulong)val.GetHashCode() * (1 + 2 * i);
}
return (int)(uint)(res ^ (res >> 32));
}
int x code>, ComputeHashfrom (x * -3, x) == 0 code> - donc si vos objets ont certaines propriétés pathologiques, vous pouvez obtenir de nombreuses collisions de code de hachage entraînant des dictionnaires et des hashsets mal performants. Ce n'est pas susceptible de se produire, mais un calcul de code de hachage de type peut éviter de tels problèmes plus facilement. Li>
- Le calcul du code HASHCODE est plus lent qu'un calcul spécialisé pourrait être. En particulier, il impliquait l'allocation de la matrice code> parames Code> et une boucle - ce qui est un peu de surcharge inutile si vous venez de recevoir deux membres à traiter. LI>
ul>
aucun des inconvénients ne provoque aucune erreur simplement inefficacité; et les deux avec apparaître dans un profileur en tant que blips dans cette méthode ou dans les internes du consommateur de code de hachage. p> p>
Pour votre mise en garde contre la vitesse, j'ajouterais que vous pouvez également produire de meilleurs codes de hachage avec une méthode de type sensible, en particulier si vous avez une idée raisonnable de quelles valeurs vont se passer le plus souvent. Je me pencherais sur la prise en charge de cela, alors la vitesse de calcul.
Le point d'une méthode aussi simple et sûre est d'être simple et sûr. Pour certaines distributions d'objets, cela aboutira à des hachons de hashcodes plus pauvres, et il prendra toujours un peu plus de temps pour calculer. Toutefois, dans le cas général, ces Hashcodes fonctionnent bien (après tout, les membres de l'OBJ constituant ont généralement des implémentations gethashcode de type de type), et la plupart des programmes ne dépensent pas la majeure partie de leur temps de fabrication ou d'utilisation de Hashcodes. A partir de l'expérience pratique, cependant, je vais noter que je suis dirigé vers GetHashCode Perf Problèmes, mais je n'ai pas eu de problèmes de qualité avec cette i> implémentation - YMMV.
En pratique, étant donné que la comparaison de l'égalité d'objet est souvent beaucoup moins chère que .gethashcode code>, vous ne payez que peu si vous rencontrez un peu de collisions i> plus. D'autre part, si vous faites beaucoup de calculs de jeu / dictionnaire, vous pouvez simplement mettre en cache le hashcode d'objets inchangés; Mais vous ne pouvez pas éviter les conséquences d'un mauvais code de hash. Quoi qu'il en soit, dans la pratique, je ne me dérangerais pas avec quelque chose de plus compliqué avant que le profilage révèle que cela en vaut la peine - ce que cela ne fait presque jamais.
Oui, je suis d'accord. Comme dit, j'ajouterais la question à votre mise en garde contre la vitesse, mais cela ne signifie pas que je ne pense pas que ce soit une méthode générale raisonnable.
C # n'a pas de constructeur de hashcode intégré, mais vous pouvez rouler le vôtre. J'ai récemment eu ce problème précis et j'ai créé ce générateur de hashcode qui n'utilise pas la boxe, en utilisant des génériques et implémente une modifiée FNV algorithme pour générer le hachage spécifique. Mais vous pouvez utiliser n'importe quel algorithme que vous voudriez, comme l'un de ceux de System.security.Cryptography code>. public static int GetHashCode<T>(params T[] args)
{
return args.GetArrayHashCode();
}
public static int GetArrayHashCode<T>(this T[] objects)
{
int[] data = new int[objects.Length];
for (int i = 0; i < objects.Length; i++)
{
T obj = objects[i];
data[i] = obj == null ? 1 : obj.GetHashCode();
}
return GetFnvHash(data);
}
private static int GetFnvHash(int[] data)
{
unchecked
{
const int p = 16777619;
long hash = 2166136261;
for (int i = 0; i < data.Length; i++)
{
hash = (hash ^ data[i]) * p;
}
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return (int)hash;
}
}
Ceci est mon constructeur fait maison.
Utilisation: p> Peu importe les champs de type Source: P> A code> b , C code> et d code> sont, faciles à prolonger, pas besoin de créer une matrice. p> public sealed class Point
{
private readonly int _x;
private readonly int _y;
private readonly int _hash;
public Point(int x, int y)
{
_x = x;
_y = y;
_hash = new HashCodeBuilder().
Add(_x).
Add(_y).
GetHashCode();
}
public int X
{
get { return _x; }
}
public int Y
{
get { return _y; }
}
public override bool Equals(object obj)
{
return Equals(obj as Point);
}
public bool Equals(Point other)
{
if (other == null) return false;
return (other._x == _x) && (other._y == _y);
}
public override int GetHashCode()
{
return _hash;
}
}
J'aime le concept d'encapsulation de ce code réutilisable. Mais il n'y a-t-il pas une pénalité de performance en raison des appels de méthode?
@Steveb dépend de la façon dont vous l'utilisez. DONNÉ, vous devez idéalement utiliser des données immuables dans des codes de hachage, si vous le faites une fois dans le constructeur, puis stockez le résultat dans un membre privé hachage code>, il est plus efficace que le calcul normal de chaque fois que le code > Gethashcode code> est appelé.
@Steveb a ajouté un exemple d'utilisation pour montrer ce que je veux dire. A également correctement la mise en œuvre des égaux.
De nos jours, je tire parti de valeur Vamples, des tuples Ref ou des types anonymes: Je pense que la valeur tuples sera la plus rapide. p> p>
Microsoft a récemment publié une classe pour calculer des hashcodes. S'il vous plaît voir https://docs.microsoft.com/en-us/ dotnet / API / System.HashCode . Vous devez inclure le package Nuget microsoft.bcl.hashcode dans votre projet à utiliser IT.
EXEMPLE D'UTILISATION: P>
using System.Collections.Generic;
public class MyClass {
public int MyVar { get; }
public string AnotherVar { get; }
public object MoreVars;
public override int GetHashCode()
=> HashCode.Combine(MyVar, AnotherVar, MoreVars);
}
C # implémentations de Murmur et XXHash ici. geteventStore.com/blog/?p=36