热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于HashCode做key的可能性

最近在设计一个分布式的key-value系统的时候中,出于性能和存储空间的考虑,准备把string类型的key替换为它的HashCode值.GetHashCode这个方法可能很多人都有所了解,不熟

最近在设计一个分布式的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)


推荐阅读
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • Java集合类中常见的hashSet,hashMap,hashTable(现已很少用,几乎都采用hashMap替代)的实现都离不开散列表,而散列表的优势在于O(1)级别的查找,而has ... [详细]
  • 如何解决《为什么这个hashCode()方法被认为很差?》经验,为你挑选了1个好方法。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • Whenoverridingtheequals()functionofjava.lang.Object,thejavadocssuggestthat,当重写java.lang. ... [详细]
  • -------------------------------------------------android培训、java培训期待与您交流!--------------------------- ... [详细]
  • 本文来自:高爽|Coder,原文地址:http:blog.csdn.netghsauarticledetails16843543,转载请注明。HashMap可以 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 1.何时需要重写equals()当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。2.为什么改写equals()的时候,总是要改写hashCode()两个原则:hashCode()的返回& ... [详细]
author-avatar
api
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有