从数组中计算单个int的更有效方法?

时间:2013-04-25 04:21:20

标签: java performance

我试图挤出我的Java Othello程序中的每一个,并且我需要计算给定数字出现的实例数。例如,数组[] {1,1,2,1,0,1}将计数(1)返回4.下面是我通过计算所有数字而在速度上进行的尝试,但速度较慢:

public void count(int color) { 
    byte count[] = new byte[3];

    for (byte i = 0; i < 64; i++)
        ++count[state[i]];

    return count[color];
}

到目前为止,这是我测试过的最有效的代码:

public void count(int color) {  
    byte count = 0;

    for (byte i = 0; i < 64; i++) 
        if (this.get(i) == color)
            count++;

    return count;
}

有人认为他们可以从中挤出更多的速度吗?我只需要指定数量的计数,仅此而已。

4 个答案:

答案 0 :(得分:2)

尝试计数int而不是byte某些架构在处理单bytes时遇到问题,因此内存中的字节较小,但进行计算时会出现问题。

答案 1 :(得分:2)

在内部使用int,而不是byte,Java将字节转换为int,然后递增,然后将其转换回字节;使用int可以避免类型转换的需要。

您也可以尝试使用AtomicInteger,其getAndIncrement方法可能比++运算符更快。

您也可以展开循环;这将减少评估i < 64的次数。尝试使用i的AtomicInteger,并使用getAndIncrement代替++

for(int i = 0; i < 64;) {
    if(this.get(i++) == color) ...
    if(this.get(i++) == color) ...
    if(this.get(i++) == color) ...
    if(this.get(i++) == color) ...
}

将for循环更改为do-while循环可能会稍快一些 - for循环有条件跳转和无条件跳转,但do-while循环只有条件跳转。

您可以并行执行此操作(thread1计算元素0-15,thread2计算元素16-31等),但创建线程的成本可能不值得。

答案 2 :(得分:0)

您可以将集合用于此目的。但是你的数组应该是Integer的类型,因为collection不支持基本类型。

public void count(int color) {  
   List<Integer> asList = Arrays.asList(your_Array);  
   return  Collections.frequency(asList,color);    
} 

答案 3 :(得分:0)

1)版本2中的this.get(i)似乎是可疑的,如果我们处理数组,则数组[i]应该更有效。

2)我会替换

byte count = 0;
for (byte i = 0; i < 64; i++) 
... 

int count = 0;
for (int i = 0; i < 64; i++) 
... 

否则Java需要将字节操作数提升为int来进行算术运算,然后将结果截断为字节。

3)使用http://code.google.com/p/caliper/获得良好的基准