我们习惯说HashMap get/put操作是O(1).但是它取决于哈希实现.默认对象哈希实际上是JVM堆中的内部地址.我们是否确定声称get/putO(1)是否足够好?
可用内存是另一个问题.据我所知,从javadocs,HashMap load factor应该是0.75.如果我们在JVM中没有足够的内存且load factor超出限制怎么办?
所以,看起来O(1)似乎不能保证.它有意义还是我错过了什么?
我正在处理一个项目,我正在处理很多推文; 我的目标是在处理它们时删除重复项.我有推文ID,它以格式的字符串形式出现"166471306949304320"
我一直在使用HashSet<String>这个,它可以正常工作一段时间.但到了大约1000万件物品的时候,我却陷入了巨大的困境,并最终得到了一个GC错误,大概是从重新开始.我试着定义一个更好的尺寸/负载
tweetids = new HashSet<String>(220000,0.80F);
这让它变得更远,但仍然非常缓慢(大约1000万,它需要花费3倍的时间来处理).我该如何优化呢?鉴于我已经大致知道在结尾集合中应该有多少项目(在这种情况下,大约20-2200万)我应该创建一个只重复两次或三次的HashSet,或者这样的开销是多少?设置了太多的时间罚款?如果我没有使用String,或者我定义了一个不同的HashCode函数(在这种情况下是String的特定实例,我不知道该怎么做),事情会更好吗?这部分实现代码如下.
tweetids = new HashSet<String>(220000,0.80F); // in constructor
duplicates = 0;
...
// In loop: For(each tweet)
String twid = (String) tweet_twitter_data.get("id");
// Check that we have not processed this tweet already
if (!(tweetids.add(twid))){
duplicates++;
continue;
}
Run Code Online (Sandbox Code Playgroud)
解
感谢您的推荐,我解决了这个问题.问题是哈希表示所需的内存量; 首先,它HashSet<String>是巨大的,不必要的,因为String.hashCode()这种规模过高.接下来,我尝试了一个Trie,但它在100多万个条目中崩溃了; 重新分配阵列是有问题的.我使用了HashSet<Long>更好的效果并且几乎成功了,但是速度衰减了,它最终在处理的最后一段(大约1900万)崩溃了.解决方案来自标准库并使用Trove.它完成了2200万条记录,比不检查重复条件快几分钟.最终的实现很简单,看起来像这样:
import gnu.trove.set.hash.TLongHashSet;
...
TLongHashSet tweetids; // class variable
...
tweetids = new TLongHashSet(23000000,0.80F); // in constructor
...
// inside for(each record) …Run Code Online (Sandbox Code Playgroud) 我有以下问题.我正在使用和API连接到某个地方并将数据作为输入流.目标是在删除重复行后保存数据.由第10,15,22列定义的重复.
我正在使用多个线程获取数据.目前我首先将数据保存到csv文件中,然后删除重复项.我想在读数据时这样做.数据量约为1000万条记录.我的内存有限,我可以使用.该机器有32GB的内存,但我有限,因为有其他应用程序使用它.
我在这里阅读有关使用哈希映射 但我不确定我有足够的记忆力来使用它.
有没有人建议如何解决这个问题?