gpt4 book ai didi

java - java中break与普通循环的性能问题

转载 作者:行者123 更新时间:2023-12-02 13:22:49 25 4
gpt4 key购买 nike

最近我做了一个不完整的非图解算器。该求解器基于迭代线求解方法。一些代码如下:

方法一:

for(; j<i; j++){
if(a[j] == 0) break;
}

方法2:

for(; j<i && a[j]!=0; j++);

这段代码在我的程序中出现了很多次。

我认为方法1和方法2做了同样的事情。但是当我在Linux机器上使用time nonogram时,当nonogram的大小约为5 x 10时,那么时间彼此非常接近,大多数时候方法2更快。当尺寸为30x40时,我运行程序大约10次,大多数时候方法1运行得比方法2快(时间差在0.2s左右)。是随机问题吗?如果只是随机问题,我会使用方法 2 而不是方法 1。它们在编译器实现上真的不同吗?谢谢。

最佳答案

我为此做了两个基本代码测试并查看了汇编代码。这就是我得到的。

方法一:

public class TestBreak {
public static void main(String[] args) {
int i = 10;
int j = 5;
int a[] = {5, 10, 6, 90, 0, 1, 0, 7, 10};
for(; j<i; j++){
if(a[j] == 0) break;
}
}
}

方法2:

public class TestBreak2 {
public static void main(String[] args) {
int i = 10;
int j = 5;
int a[] = {5, 10, 6, 90, 0, 1, 0, 7, 10};
for(; j<i && a[j] != 0; j++){
}
}
}

方法1的汇编代码:

public class TestBreak {
public TestBreak();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: bipush 10
2: istore_1
3: iconst_5
4: istore_2
5: bipush 9
7: newarray int
9: dup
10: iconst_0
11: iconst_5
12: iastore
13: dup
14: iconst_1
15: bipush 10
17: iastore
18: dup
19: iconst_2
20: bipush 6
22: iastore
23: dup
24: iconst_3
25: bipush 90
27: iastore
28: dup
29: iconst_4
30: iconst_0
31: iastore
32: dup
33: iconst_5
34: iconst_1
35: iastore
36: dup
37: bipush 6
39: iconst_0
40: iastore
41: dup
42: bipush 7
44: bipush 7
46: iastore
47: dup
48: bipush 8
50: bipush 10
52: iastore
53: astore_3
54: iload_2
55: iload_1
56: if_icmpge 74
59: aload_3
60: iload_2
61: iaload
62: ifne 68
65: goto 74
68: iinc 2, 1
71: goto 54
74: return
}

方法2的汇编代码:

public class TestBreak2 {
public TestBreak2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: bipush 10
2: istore_1
3: iconst_5
4: istore_2
5: bipush 9
7: newarray int
9: dup
10: iconst_0
11: iconst_5
12: iastore
13: dup
14: iconst_1
15: bipush 10
17: iastore
18: dup
19: iconst_2
20: bipush 6
22: iastore
23: dup
24: iconst_3
25: bipush 90
27: iastore
28: dup
29: iconst_4
30: iconst_0
31: iastore
32: dup
33: iconst_5
34: iconst_1
35: iastore
36: dup
37: bipush 6
39: iconst_0
40: iastore
41: dup
42: bipush 7
44: bipush 7
46: iastore
47: dup
48: bipush 8
50: bipush 10
52: iastore
53: astore_3
54: iload_2
55: iload_1
56: if_icmpge 71
59: aload_3
60: iload_2
61: iaload
62: ifeq 71
65: iinc 2, 1
68: goto 54
71: return
}

如您所见,唯一的区别是方法 1 的汇编代码中的一行:

62: ifne          68

除此之外,它们生成相似的字节代码,因此性能差异可能并不大。

如果您确实想衡量哪个更快,请编写一个微基准测试。为此,请遵循此处解释的规则:How do I write a correct micro-benchmark in Java? .

另一条信息:如果您确实想要发现应用程序中的性能瓶颈,请使用探查器,它会明确告诉您哪些瓶颈方法比其他方法消耗更多的 cpu,然后将精力放在解决该方法的性能问题上,而不是猜测问题可能出在哪里。

关于如何生成字节码,请阅读javap命令,特别是javap -c

关于java - java中break与普通循环的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19509212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com