zoukankan      html  css  js  c++  java
  • 关于 HashCode做key的可能性

    最近在设计一个分布式的key-value系统的时候中,出于性能和存储空间的考虑,准备把string类型的key替换为它的HashCode值.

    GetHashCode这个方法可能很多人都有所了解,不熟悉的可以看看这里:http://msdn.microsoft.com/zh-cn/library/system.object.gethashcode.aspx

    以下信息只限于String.GetHashCode,其他的例如Object.GetHashCode根据其他对象的实现不同而不同:

    1.对于不同的对象类型,或者同类型的不同值,返回值是可能重复的

    2.String.GetHashCode的实现是平台相关的,32位版本和64位版本并不一样

    3.String.GetHashCode的实现和.net版本有关,将来可能还会改变

    4.同样的程序集,同样的平台,同样的字符串, 返回同样的HashCode

    5.基于默认实现,虽然对象是会重复的,但是由于hashcode是int32类型并且实现的比较良好,那么只有当数据量达到或者接近2^32数量级的时候才需要考虑重复的情况

    • 2^32次方大约在40多亿
    • 假设有1千万数据,那么有一条或者多余一条数据重复的可能性约为400分之一 (这个概率对于一个要求较高的系统来说太危险了,而且现在很多系统的数据是远大于千万级别的)

    6. .net4.0里面String.GetHashCode的实现代码如下

            // Gets a hash code for this string.  If strings A and B are such that A.Equals(B), then 
    // they will return the same hash code.
    [System.Security.SecuritySafeCritical] // auto-generated
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    public override int GetHashCode() {
    unsafe {
    fixed (char *src = this) {
    Contract.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'");
    Contract.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");

    #if WIN32
    int hash1 = (5381<<16) + 5381;
    #else
    int hash1 = 5381;
    #endif
    int hash2 = hash1;

    #if WIN32
    // 32bit machines.
    int* pint = (int *)src;
    int len = this.Length;
    while(len > 0) {
    hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
    if( len <= 2) {
    break;
    }
    hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1];
    pint += 2;
    len -= 4;
    }
    #else
    int c;
    char *s = src;
    while ((c = s[0]) != 0) {
    hash1 = ((hash1 << 5) + hash1) ^ c;
    c = s[1];
    if (c == 0)
    break;
    hash2 = ((hash2 << 5) + hash2) ^ c;
    s += 2;
    }
    #endif
    #if DEBUG
    // We want to ensure we can change our hash function daily.
    // This is perfectly fine as long as you don't persist the
    // value from GetHashCode to disk or count on String A
    // hashing before string B. Those are bugs in your code.
    hash1 ^= ThisAssembly.DailyBuildNumber;
    #endif
    return hash1 + (hash2 * 1566083941);
    }
    }
    }

    考虑到GetHashCode依赖.net版本和平台,还有重复概率..还是放弃了用HashCode来代替Key的想法

    最终选择使用md5 (16 bytes)

  • 相关阅读:
    AtCoder Regular Contest 093
    AtCoder Regular Contest 094
    G. Gangsters in Central City
    HGOI 20190711 题解
    HGOI20190710 题解
    HGOI 20190709 题解
    HGOI 20190708 题解
    HGOI20190707 题解
    HGOI20190706 题解
    HGOI 20190705 题解
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2277530.html
Copyright © 2011-2022 走看看