01-Kotlin的WhenElse一共有几种写法

Int等基本类型的WhenElse

1
2
3
4
5
6
7
8
9
private fun whenElseInt(intNumber: Int) {
val number: String = when(intNumber) {
0 -> "Zero"
1 -> "One"
2 -> "Two"
else -> "Unknown"
}
println(number)
}

编译后的字节码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private final static whenElseInt(I)V
L0
LINENUMBER 22 L0
ILOAD 0
TABLESWITCH
0: L1
1: L2
2: L3
default: L4
L1
LINENUMBER 23 L1
FRAME SAME
LDC "Zero"
GOTO L5
L2
LINENUMBER 24 L2
FRAME SAME
LDC "One"
GOTO L5
L3
LINENUMBER 25 L3
FRAME SAME
LDC "Two"
GOTO L5
L4
LINENUMBER 26 L4
FRAME SAME
LDC "Unknown"
L5
LINENUMBER 22 L5
FRAME SAME1 java/lang/String
ASTORE 1
L6
LINENUMBER 28 L6
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 1
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
L7
LINENUMBER 29 L7
RETURN
L8
LOCALVARIABLE number Ljava/lang/String; L6 L8 1
LOCALVARIABLE intNumber I L0 L8 0
MAXSTACK = 2
MAXLOCALS = 2

可以看到,编译器生成了TABLESWITCH指令,可以根据数值快速查表,找到跳转位置

如果是一下几种情况,则不会生成TABLESWITCH

阅读更多

00-Java数组遍历性能对比

三种遍历方式性能对比

  1. 循环与数组的length比较

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class JavaMain {
    static Object[] objs = new Object[10000000];
    static int zero() {
    int sum = 0;
    for(int i = 0; i < objs.length; i++) {
    sum ^= objs[i].hashCode();
    }
    return sum;
    }
    }
  2. 将数组length存在方法栈中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class JavaMain {
    static Object[] objs = new Object[10000000];
    static int one() {
    int sum = 0;
    int len = objs.length;
    for(int i = 0; i < len; i++) {
    sum ^= objs[i].hashCode();
    }
    return sum;
    }
    }
  3. for-each循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class JavaMain {
    static Object[] objs = new Object[10000000];
    static int two() {
    int sum = 0;
    for (Object obj : objs) {
    sum ^= obj.hashCode();
    }
    return sum;
    }
    }

测试速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class JavaMain {
static Object[] objs = new Object[10000000];
static long run(IntSupplier f) {
long start = System.currentTimeMillis();
int result = 0;
for(int i = 0; i < 100; i++) {
result = f.getAsInt();
}
long end = System.currentTimeMillis();
System.out.println("result = " + result + ", time = " + (end - start) / 1000.0);
return end - start;
}
public static void main(String[] args) {
for (int i = 0; i < objs.length; i++) {
objs[i] = new Object();
objs[i].hashCode(); // 首次计算hashcode更慢,先缓存
}
for (int i = 0; i < 10; i++) {
long zeroTime = run(JavaMain::zero);
long oneTime = run(JavaMain::one);
long twoTime = run(JavaMain::two);
System.out.printf("2比1快: %.2f%%\n", ((double)oneTime - twoTime) / oneTime * 100);
System.out.printf("2比0快: %.2f%%\n", ((double)zeroTime - twoTime) / zeroTime * 100);
System.out.printf("1比0快: %.2f%%\n", ((double)zeroTime - oneTime) / oneTime * 100);
}
}
}

测试结果

1
2
3
4
5
6
result = 360970567, time = 1.393
result = 360970567, time = 1.174
result = 360970567, time = 0.886
2比1快: 24.53%
2比0快: 36.40%
1比0快: 18.65%
阅读更多