• 关于 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)

  • 相关阅读:
    排序算法【java实现】(二)冒泡排序和简单选择排序
    排序算法【java实现】(一)直接插入排序
    Html中行内元素和块级元素有哪些?
    设计模式--单例模式(二)双重校验锁模式
    设计模式--单例模式(一)懒汉式和饿汉式
    给定一个字符串数组{"nba","abc","cba","zz","qq","haha"},请按照字典顺序进行从小到大的排序。
    请统计"nba"在字符串"nbaernbatynbauinbaopnba"中出现的次数
    java string方法
    css中的颜色值
    jquery动画效果中,避免持续反应用户的连续点击
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/2277530.html
Copyright © 2020-2023  润新知