Java中假设存在一个2维数组
byte[][] byteArr;
int i,n;
byte a,d;
long lsum;请猜下面2段代码效率哪个高?
代码1 a = byteArr[i][n];
if(a > 0 && a < 10)
lsum += a;
代码2 a = byteArr[i][n];
d = (byte)(Math.abs(a - 5)); if(d < 5)
lsum += a;
以上在计算量超大的时候进行的测试。
如下测试代码 Random rnd = new Random();
long lsum = 0;
byte[][] byteArr = new byte[2000][1000];
for(int i = 0; i < 2000; i++)
{
for(int n = 0; n < 1000; n++)
{
byteArr[i][n] = (byte)(rnd.nextInt());
}
}
byte a = 0;
byte d = 0;
long t11 = new Date().getTime();
for(int t = 0; t < 2000; t++)
{
for(int i = 0; i < 1000; i++)
{
for(int n = 0; n < 1000; n++)
{
a = byteArr[i][n];
if(a > 0 && a < 10)
lsum += a;
}
}
}
long t12 = new Date().getTime();
long t21 = new Date().getTime();
for(int t = 0; t < 2000; t++)
{
for(int i = 0; i < 1000; i++)
{
for(int n = 0; n < 1000; n++)
{
a = byteArr[i][n];
d = (byte)(Math.abs(a - 5)); if(d < 5)
lsum += a;
}
}
}
long t22 = new Date().getTime(); System.out.println("t11 - t12: " + (t12 - t11));
System.out.println("t21 - t22: " + (t22 - t21));结果是第一段的执行时间几乎是第2段的2.5倍。本人对Java底层了解不深,特此求解。Java测试效率二维数组
byte[][] byteArr;
int i,n;
byte a,d;
long lsum;请猜下面2段代码效率哪个高?
代码1 a = byteArr[i][n];
if(a > 0 && a < 10)
lsum += a;
代码2 a = byteArr[i][n];
d = (byte)(Math.abs(a - 5)); if(d < 5)
lsum += a;
以上在计算量超大的时候进行的测试。
如下测试代码 Random rnd = new Random();
long lsum = 0;
byte[][] byteArr = new byte[2000][1000];
for(int i = 0; i < 2000; i++)
{
for(int n = 0; n < 1000; n++)
{
byteArr[i][n] = (byte)(rnd.nextInt());
}
}
byte a = 0;
byte d = 0;
long t11 = new Date().getTime();
for(int t = 0; t < 2000; t++)
{
for(int i = 0; i < 1000; i++)
{
for(int n = 0; n < 1000; n++)
{
a = byteArr[i][n];
if(a > 0 && a < 10)
lsum += a;
}
}
}
long t12 = new Date().getTime();
long t21 = new Date().getTime();
for(int t = 0; t < 2000; t++)
{
for(int i = 0; i < 1000; i++)
{
for(int n = 0; n < 1000; n++)
{
a = byteArr[i][n];
d = (byte)(Math.abs(a - 5)); if(d < 5)
lsum += a;
}
}
}
long t22 = new Date().getTime(); System.out.println("t11 - t12: " + (t12 - t11));
System.out.println("t21 - t22: " + (t22 - t21));结果是第一段的执行时间几乎是第2段的2.5倍。本人对Java底层了解不深,特此求解。Java测试效率二维数组
if(a > 0 && a < 10)
这里进行的是两个判断,当然,&&是具有短路性的,第一个判断不成立时第二个直接跳过。所以应该比一个判断的效率低一些,但不会达到2倍的程度。if(d < 5)这里就一个判断,效率自然应该高一些。所以我感觉8比5的时间在理论上讲也许更适合一些。
环境是
dual-CORE E5800
WIN XP 32位 SP3
4G 内存
JAVA 1.6先前测试时间是2.5:1
环境是
I7 3770
WIN 7 64位
8G内存
JAVA 1.7
I7用时大概是6.5s : 2.8sdual用时大概是24.5s : 40.3s
public static int abs(int a) {
return (a < 0) ? -a : a;
}
这里做了一次判断,而且做了一次"-"运算。abs的消耗更大一些。这里的结果第一段慢,是因为你的测试是错的。byteArr里如果有一个比如说-125,那么-125 - 5 = -130,abs(-130) = 130,(byte) 130 = -126,于是-125被错误地加入了lsum。如果你把
byte d = 0;
d = (byte)(Math.abs(a - 5));改成int d = 0;
d = Math.abs(a - 5);那两段代码测试结果应该是相似的,而且第一段略快一些。至于你要问,为什么错的时候快的那段代码反而是lsum+=a执行得多的那段,我便不能解释了。也许JVM在编译的时候预判c < 5的几率较大,所以直接执行c<5后的语句比调用一次branch更快?这个我真的是瞎猜,但是要测谁的性能好,前提是公平测试。改进过后的测试程序:
import java.util.Random;class Test {
private static byte[][] byteArr; public static void main(final String[] args) {
Random rnd = new Random(); byteArr = new byte[200][100];
for (int i = 0; i < 200; i++) {
for (int n = 0; n < 100; n++) {
byteArr[i][n] = (byte) (rnd.nextInt());
}
} test1(10000); //warm up
test2(10000); //warm up test1(1000);
test2(1000); test2(1000);
test1(1000); test1(1000);
test2(1000); test2(1000);
test1(1000);
} static void test1(int rounds) {
long startTime = System.nanoTime();
long sum = 0;
for (int i = 0; i < rounds; i++) {
sum = testRoutine1();
}
long endTime = System.nanoTime();
System.out.println("Test1: " + (endTime - startTime) + " " + sum);
} static void test2(int rounds) {
long sum = 0;
long startTime = System.nanoTime();
for (int i = 0; i < rounds; i++) {
sum = testRoutine2();
}
long endTime = System.nanoTime();
System.out.println("Test2: " + (endTime - startTime) + " " + sum);
} static long testRoutine1() {
long lsum = 0;
for (int i = 0; i < 200; i++) {
for (int n = 0; n < 100; n++) {
byte b = byteArr[i][n];
int c = Math.abs(b - 5);
if (c < 5) {
lsum += b;
}
}
}
return lsum;
} static long testRoutine2() {
long lsum = 0;
for (int i = 0; i < 200; i++) {
for (int n = 0; n < 100; n++) {
byte b = byteArr[i][n];
if (b > 0 && b < 10) {
lsum += b;
}
}
}
return lsum;
}
}
之前测试的结果是第一段快,第二段慢,按照开始的解释应该第二段加操作多过第一段,且abs效率低,其实还是跟原先疑惑的情况不吻合的。不管如何,多谢费心解答