计算事件的最有效方法?

时间:2015-05-06 17:26:24

标签: java performance counting

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

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

此单线程需要约500毫秒来处理长度 24883200 字节[] 。 使用常规进行循环需要至少 600毫秒。

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

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

我使用的是Java 8,如果可能,我更愿意避免使用Apache Commons。

2 个答案:

答案 0 :(得分:15)

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

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

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

答案 1 :(得分:8)

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

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

那样:

  • 您永远不需要对键或值进行任何装箱
  • 没有什么需要采用哈希码,检查是否平等等
  • 它的内存效率与
  • 相同

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