是否有办法实现内存高效的“ID生成”URL?
目前我的网址有一个缓存ala Set<String>
,我可以轻松检查我的抓取工具是否已经解析了该网址。现在这需要大量内存,我用Set<Long>
替换它并使用了URL的hashCode。现在的问题是,即使是40k的URL也有10个冲突。使用long而不是int hashCode
的改进方法可以将它改为6次冲突,但特别是短网址在开始时看起来非常相似:
5852015146777169869 http://twitpic.com/5xuwuk vs. http://twitpic.com/5xuw7m 5852015146777169869
所以我最终得到了以下特定于URL的双重散列方法,它没有为2.5mio URL提供冲突,这对我来说很好:
public static long urlHashing(String str) {
if (str.length() < 2)
return str.hashCode();
long val = longHashCode(str, 31, false);
if (str.length() > 3)
// use the end of the string because those short URLs
// are often identical at the beginning
return 43 * val + longHashCode(str.substring(str.length() / 2), 37, true);
return val;
}
public static long longHashCode(String str, int num, boolean up) {
int len = str.length();
if (len == 0)
return 0;
long h = 0;
// copying to a temp arry is a only a tiny bit slower in our case.
// so this here is ~2ms faster for 40k urls
if (up)
for (int i = 0; i < len;) {
h = num * h + str.charAt(i++);
}
else
for (int i = len - 1; i >= 0;) {
h = num * h + str.charAt(i--);
}
return h;
}
但现在我想知道:是否有一些关于URL特定散列算法的理论或(google;))论文?或者简单地说:我可以进一步减少URL的冲突,还是看到我当前的解决方案有任何问题或改进?
更新
new URL(str).hashCode()
方法中完成一样(由于速度非常慢而无法直接使用 - &gt;它可以动态解析URL: /)答案 0 :(得分:3)
如果你想要的东西一直有效,而不仅仅是大部分时间,短暂的哈希不会削减它。正如您所观察到的,在任何长度短于大约128位的情况下,即使理想的散列也会具有显着的冲突率。你所拥有的是一个扩展问题,你使用哈希码完成的只是减少常数因子 - 它仍然是O(n)。
听起来你的字符串有很多共同的前缀 - 你考虑使用trie来存储它们吗?
答案 1 :(得分:2)
您应该使用MD5 hash。碰撞率应该小得多。