我试图挤出我的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;
}
有人认为他们可以从中挤出更多的速度吗?我只需要指定数量的计数,仅此而已。
答案 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/获得良好的基准