计算事件的最有效方法?

tof*_*ffe 5 java performance counting

我有一个字节数组(原始),它们可以有随机值.我试图以最有效/最快的方式计算它们在数组中的出现次数.目前我正在使用:

HashMap<Byte, Integer> dataCount = new HashMap<>();
for (byte b : data) dataCount.put(b, dataCount.getOrDefault(b, 0) + 1);
Run Code Online (Sandbox Code Playgroud)

这个单行程需要大约500ms来处理长度为24883200字节[].使用常规for循环至少需要600ms.

我一直在考虑构造一个集合(因为它们只包含每个元素中的一个),然后使用Collections.frequency()将它添加到HashMap ,但是从原语构造Set的方法需要几个其他调用,所以我是猜测它不是那么快.

完成每个项目发生次数的最快方法是什么?

我正在使用Java 8,如果可能的话,我宁愿避免使用Apache Commons.

Lou*_*man 15

如果它只是字节,请使用数组,不要使用地图.你必须使用掩码来处理字节的签名,但这不是什么大问题.

int[] counts = new int[256];
for (byte b : data) {
   counts[b & 0xFF]++;
}
Run Code Online (Sandbox Code Playgroud)

阵列非常紧凑和高效,当你可以使用时几乎不可能击败它们.

  • `int []`比_HashMap更紧凑,"不存在的值的内存"几乎肯定是通过不使用`HashMap`来支付的.根据计数的大小,如果你有甚至~20个不同的字节,那么`int [256]`会更好,而所有其他236个值都是0. (5认同)

Jon*_*eet 8

我会创建一个数组而不是a HashMap,因为你确切知道需要跟踪的计数数量:

int[] counts = new int[256];
for (byte b : data) {
    counts[b & 0xff]++;
}
Run Code Online (Sandbox Code Playgroud)

那样:

  • 你永远不需要对键或值进行任何装箱
  • 没有什么需要采用哈希码,检查相等性等
  • 它与内存一样高效

请注意,& 0xff它用于获取范围内的值[0, 255]而不是[-128, 127],因此它适合作为数组的索引.

  • 我不认为我曾经见过同时出现的2*个相同的*代码片段. (3认同)