Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最有效的计数方法是什么?_Java_Performance_Counting - Fatal编程技术网

Java 最有效的计数方法是什么?

Java 最有效的计数方法是什么?,java,performance,counting,Java,Performance,Counting,我有一个字节数组(原语),它们可以有随机值。我试图以最高效/最快的方式计算它们在阵列中的出现次数。目前我正在使用: HashMap<Byte, Integer> dataCount = new HashMap<>(); for (byte b : data) dataCount.put(b, dataCount.getOrDefault(b, 0) + 1); HashMap dataCount=newhashmap(); 对于(字节b:数据)dataCount.put

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

HashMap<Byte, Integer> dataCount = new HashMap<>();
for (byte b : data) dataCount.put(b, dataCount.getOrDefault(b, 0) + 1);
HashMap dataCount=newhashmap();
对于(字节b:数据)dataCount.put(b,dataCount.getOrDefault(b,0)+1);
这一行程序处理长度为24883200的字节[]需要约500毫秒。 使用常规for循环至少需要600毫秒

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

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


我使用的是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
用于获取范围
[0255]
中的值,而不是
[-128127]
,因此它适合作为数组的索引。

这会起作用,但它也会为未出现的值分配内存,稍后我需要这些值的哈希映射,当然没有0值。似乎增长太大了,我能负担得起创建HashMap的后续副本!一个
int[]
比一个
HashMap
要紧凑得多,以至于“没有出现的值的内存”几乎肯定是通过不使用
HashMap
来支付的。根据计数的大小,
int[256]
如果有20个不同的字节,其他236个值都是0,就更好了。我想我以前从未见过两段相同的代码同时出现。@pbabcdefp:Louis的代码有大写十六进制数,三个空格而不是4:)他的是第一位,这就是为什么我接受了它,因为没有太大的区别:)