计算大长数组中的不同值(性能问题)

时间:2016-01-08 23:35:48

标签: java performance hashset

我有这个:

long hnds[] = new long[133784560]; // 133 million

然后我快速填充数组(几个ms),然后我想知道唯一(即不同)值的数量。现在,我甚至不需要这个实时,我只需要尝试一些变化,看看每个变量有多少。

我试过,例如这样:

import org.apache.commons.lang3.ArrayUtils;
....
HashSet<Long> length = new HashSet<Long>(Arrays.asList(ArrayUtils.toObject(hnds)));
System.out.println("size: " + length.size());

等待半小时后,它会产生堆空间错误(我有Xmx4000m)。

我也尝试初始化Long [] hnds而不是long [] hnds,但是数组的初始填充需要永远。或者例如在添加值时从头开始使用Set,但也需要永远。有没有办法计算long []数组的不同值而无需永远等待?如果必须的话,我会把它写到文件中。

2 个答案:

答案 0 :(得分:2)

我最好的建议是使用像fastutil(http://fastutil.di.unimi.it/)之类的库,然后使用自定义的未装箱哈希集:

import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
System.out.println(new LongOpenHashSet(hnds).size());

(另外,顺便说一下,如果你能接受大概的答案,你可以尝试 更多更有效的算法;详见this paper。)

答案 1 :(得分:1)

只需对它进行排序并计算。

 int sz = 133784560;
 Random randy = new Random();
 long[] longs = new long[sz];
 for(int i = 0; i < sz; i++) { longs[i] = randy.nextInt(10000000); }
 Arrays.sort(longs);
 long lastSeen = longs[0];
 long count = 0;
 for(int i = 1; i < sz; i++) {
   if(longs[i] != lastSeen) count++;
   lastSeen = longs[i];
 }

我的笔记本电脑大约需要15秒。