计算出现次数的最有效方法?
Most efficient way to count occurrences?
我有一个字节数组(原始),它们可以有随机值。我正在尝试以最 efficient/fastest 的方式计算它们在数组中的出现次数。目前我正在使用:
HashMap<Byte, Integer> dataCount = new HashMap<>();
for (byte b : data) dataCount.put(b, dataCount.getOrDefault(b, 0) + 1);
这个单行代码需要大约 500 毫秒来处理长度为 24883200 的 byte[]。
使用常规 for 循环需要 至少 600 毫秒。
我一直在考虑构建一个集合(因为它们只包含每个元素之一)然后使用 Collections.frequency() 将其添加到 HashMap,但是从基元构造 Set 的方法需要其他几个调用,所以我猜它没有那么快。
完成每个项目出现次数计数的最快方法是什么?
我正在使用 Java 8,我希望尽可能避免使用 Apache Commons。
如果只是字节,请使用数组,不要使用映射。您确实必须使用掩码来处理字节的符号,但这没什么大不了的。
int[] counts = new int[256];
for (byte b : data) {
counts[b & 0xFF]++;
}
数组非常紧凑和高效,当您可以使用它们时,它们几乎不可能被击败。
我会创建一个 数组 而不是 HashMap
,前提是您确切知道需要跟踪多少计数:
int[] counts = new int[256];
for (byte b : data) {
counts[b & 0xff]++;
}
这样:
- 您永远不需要对键或值进行任何装箱
- 无需获取哈希码、检查相等性等
- 它的内存效率差不多了
请注意,& 0xff
用于获取 [0, 255]
范围内的值而不是 [-128, 127]
,因此它适合作为数组的索引。
我有一个字节数组(原始),它们可以有随机值。我正在尝试以最 efficient/fastest 的方式计算它们在数组中的出现次数。目前我正在使用:
HashMap<Byte, Integer> dataCount = new HashMap<>();
for (byte b : data) dataCount.put(b, dataCount.getOrDefault(b, 0) + 1);
这个单行代码需要大约 500 毫秒来处理长度为 24883200 的 byte[]。 使用常规 for 循环需要 至少 600 毫秒。
我一直在考虑构建一个集合(因为它们只包含每个元素之一)然后使用 Collections.frequency() 将其添加到 HashMap,但是从基元构造 Set 的方法需要其他几个调用,所以我猜它没有那么快。
完成每个项目出现次数计数的最快方法是什么?
我正在使用 Java 8,我希望尽可能避免使用 Apache Commons。
如果只是字节,请使用数组,不要使用映射。您确实必须使用掩码来处理字节的符号,但这没什么大不了的。
int[] counts = new int[256];
for (byte b : data) {
counts[b & 0xFF]++;
}
数组非常紧凑和高效,当您可以使用它们时,它们几乎不可能被击败。
我会创建一个 数组 而不是 HashMap
,前提是您确切知道需要跟踪多少计数:
int[] counts = new int[256];
for (byte b : data) {
counts[b & 0xff]++;
}
这样:
- 您永远不需要对键或值进行任何装箱
- 无需获取哈希码、检查相等性等
- 它的内存效率差不多了
请注意,& 0xff
用于获取 [0, 255]
范围内的值而不是 [-128, 127]
,因此它适合作为数组的索引。