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)

  • 相关阅读:
    Outlook 邮件助手
    飞花令
    青蛙跳台阶
    如何提问,找到去说谎国的路
    如何计时一个小时十五分钟
    旋转数组的最小元素
    谁养鱼?
    小龙赚了多少?
    下一行是什么?
    5 = ?
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2277530.html
Copyright © 2011-2022 走看看