最近在网上看到一片文章,说switch和if-else相比,由于使用了Binary Tree算法,绝大部分情况下switch会快一点,除非是if-else的第一个条件就为true,还给出了个例子,后来我把例子改了一下,如下:
public class SwitchAndIf {
public static void main(String args[]) {
System.out.println(3);
SwitchAndIf.caseIf(3);
SwitchAndIf.caseSwitch(3);
System.out.println("------------------------------------");
System.out.println(5);
SwitchAndIf.caseIf(5);
SwitchAndIf.caseSwitch(5);
System.out.println("------------------------------------");
System.out.println(7);
SwitchAndIf.caseIf(7);
SwitchAndIf.caseSwitch(7);
System.out.println("------------------------------------");
System.out.println(2);
SwitchAndIf.caseIf(2);
SwitchAndIf.caseSwitch(2);
System.out.println("------------------------------------");
System.out.println(6);
SwitchAndIf.caseIf(6);
SwitchAndIf.caseSwitch(6);
System.out.println("------------------------------------");
System.out.println(4);
SwitchAndIf.caseIf(4);
SwitchAndIf.caseSwitch(4);
System.out.println("------------------------------------");
System.out.println(1);
SwitchAndIf.caseIf(1);
SwitchAndIf.caseSwitch(1);
System.out.println("------------------------------------");
System.out.println(8);
SwitchAndIf.caseIf(8);
SwitchAndIf.caseSwitch(8);
} public static void caseSwitch(int a) {
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
switch (a) {
case 3:
break;
case 5:
break;
case 7:
break;
case 2:
break;
case 6:
break;
case 4:
break;
case 1:
break;
case 8:
break;
}
}
long e = System.currentTimeMillis();
System.out.println("Switch Cost: " + (e - s));
} public static void caseIf(int a) {
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
if (a == 3) {
} else if (a == 5) {
} else if (a == 7) {
} else if (a == 2) {
} else if (a == 6) {
} else if (a == 4) {
} else if (a == 1) {
} else if (a == 8) {
}
}
long e = System.currentTimeMillis();
System.out.println("If Cost: " + (e - s));
}
}
但是发现运算结果是:
3
If Cost: 1485
Switch Cost: 2546
------------------------------------
5
If Cost: 1969
Switch Cost: 3422
------------------------------------
7
If Cost: 2438
Switch Cost: 4375
------------------------------------
2
If Cost: 2921
Switch Cost: 1985
------------------------------------
6
If Cost: 3406
Switch Cost: 3969
------------------------------------
4
If Cost: 3906
Switch Cost: 2922
------------------------------------
1
If Cost: 4391
Switch Cost: 1484
------------------------------------
8
If Cost: 4484
Switch Cost: 4969反而switch出于下风,那篇帖子说的是JDK1.4,我用的是JDK1.6,为什么会出现这种现象呢?就算是二叉树算法,至少也应该是单数位会快一点吧?
难道是JDK1.6中的switch换算法了?
盼各位大虾指教!
public class SwitchAndIf {
public static void main(String args[]) {
System.out.println(3);
SwitchAndIf.caseIf(3);
SwitchAndIf.caseSwitch(3);
System.out.println("------------------------------------");
System.out.println(5);
SwitchAndIf.caseIf(5);
SwitchAndIf.caseSwitch(5);
System.out.println("------------------------------------");
System.out.println(7);
SwitchAndIf.caseIf(7);
SwitchAndIf.caseSwitch(7);
System.out.println("------------------------------------");
System.out.println(2);
SwitchAndIf.caseIf(2);
SwitchAndIf.caseSwitch(2);
System.out.println("------------------------------------");
System.out.println(6);
SwitchAndIf.caseIf(6);
SwitchAndIf.caseSwitch(6);
System.out.println("------------------------------------");
System.out.println(4);
SwitchAndIf.caseIf(4);
SwitchAndIf.caseSwitch(4);
System.out.println("------------------------------------");
System.out.println(1);
SwitchAndIf.caseIf(1);
SwitchAndIf.caseSwitch(1);
System.out.println("------------------------------------");
System.out.println(8);
SwitchAndIf.caseIf(8);
SwitchAndIf.caseSwitch(8);
} public static void caseSwitch(int a) {
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
switch (a) {
case 3:
break;
case 5:
break;
case 7:
break;
case 2:
break;
case 6:
break;
case 4:
break;
case 1:
break;
case 8:
break;
}
}
long e = System.currentTimeMillis();
System.out.println("Switch Cost: " + (e - s));
} public static void caseIf(int a) {
long s = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
if (a == 3) {
} else if (a == 5) {
} else if (a == 7) {
} else if (a == 2) {
} else if (a == 6) {
} else if (a == 4) {
} else if (a == 1) {
} else if (a == 8) {
}
}
long e = System.currentTimeMillis();
System.out.println("If Cost: " + (e - s));
}
}
但是发现运算结果是:
3
If Cost: 1485
Switch Cost: 2546
------------------------------------
5
If Cost: 1969
Switch Cost: 3422
------------------------------------
7
If Cost: 2438
Switch Cost: 4375
------------------------------------
2
If Cost: 2921
Switch Cost: 1985
------------------------------------
6
If Cost: 3406
Switch Cost: 3969
------------------------------------
4
If Cost: 3906
Switch Cost: 2922
------------------------------------
1
If Cost: 4391
Switch Cost: 1484
------------------------------------
8
If Cost: 4484
Switch Cost: 4969反而switch出于下风,那篇帖子说的是JDK1.4,我用的是JDK1.6,为什么会出现这种现象呢?就算是二叉树算法,至少也应该是单数位会快一点吧?
难道是JDK1.6中的switch换算法了?
盼各位大虾指教!
解决方案 »
- 如何读取log里面的字符串
- 看下,谢谢。
- 求算法!
- [求助]需要转换txt数据到mysql数据库,没思路,哪位大侠可以指条明路(欢迎砸帖)
- 使用FileReader类、LineNumberReader类是否只能抛出IOException,不能抛出自定义类,请详细解释!
- 推荐网站---matrix 开源技术---www.matrix.org.cn
- 一个关于线程的问题。
- 执行insert into 时显示科学计数法是怎么回事?
- J2SE,J2EE什么意思,我是初学者
- “当某个实例不再被任何对象引用时就会被垃圾回收机制回收”,那么怎样才算是不被任何对象引用呢?
- 一道求质数的题目
- socket编程:TCP聊天程序
对于case的分支比较密集的情况,如 Java code
public class Test { public static void main(String[] args) {
int i = 3;
switch (i) {
case 0:
System.out.println("0");
break;
case 1:
System.out.println("1");
break;
case 3:
System.out.println("3");
break;
case 5:
System.out.println("5");
break;
case 10:
System.out.println("10");
break;
case 13:
System.out.println("13");
break;
case 14:
System.out.println("14");
break;
default:
System.out.println("default");
break;
}
}
}使用tableswitch,得到 Java code
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iload_1
3: tableswitch{ //0 to 14
0: 76;
1: 87;
2: 153;
3: 98;
4: 153;
5: 109;
6: 153;
7: 153;
8: 153;
9: 153;
10: 120;
11: 153;
12: 153;
13: 131;
14: 142;
default: 153 }
76: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
79: ldc #3; //String 0
81: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
84: goto 161
87: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
90: ldc #5; //String 1
92: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
95: goto 161
98: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
101: ldc #6; //String 3
103: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
106: goto 161
109: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
112: ldc #7; //String 5
114: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
117: goto 161
120: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
123: ldc #8; //String 10
125: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
128: goto 161
131: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
134: ldc #9; //String 13
136: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
139: goto 161
142: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
145: ldc #10; //String 14
147: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
150: goto 161
153: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
156: ldc #11; //String default
158: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
161: return}从中可以看到tableswitch使用的跳转表。它这样查找,如果case值不在//0 to 14之间,直接执行default,如果在此范围之内,则取目标值-0这一项作为目标,比如switch(i),i为3,则跳转到3-0=3,使用数组中的第三项作为目标,也就是3: 98;直接去执行98行。 如果case中的值比较稀疏,则使用lookupswitch: Java code
public class Test2 { public static void main(String[] args) {
int i = 3;
switch (i) {
case 3:
System.out.println("3");
break;
case 20:
System.out.println("20");
break;
case 50:
System.out.println("50");
break;
case 100:
System.out.println("100");
break;
}
}
}编译为 Java code
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iload_1
3: lookupswitch{ //4
3: 44;
20: 55;
50: 66;
100: 77;
default: 85 }
44: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
47: ldc #3; //String 3
49: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
52: goto 85
55: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
58: ldc #5; //String 20
60: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
63: goto 85
66: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
69: ldc #6; //String 50
71: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
74: goto 85
77: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
80: ldc #7; //String 100
82: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
85: return
可以看到其中的
3: lookupswitch{ //4
3: 44;
20: 55;
50: 66;
100: 77;
default: 85 }
这个就要挨着查表确定跳转位置了。
只是在实际开发中 没有人会去用很多很多else if的
都是用 switch case 的 后者比较清晰 给人感觉就是一个脑子很清楚的人写出来的东西
至于效率的本质 就让大企鹅去操心吧
事由整体结构决定的!除非是开发编译器,偏执在这种问题上没有任何意义。
事由整体结构决定的! 除非是开发编译器,偏执在这种问题上没有任何意义。