Ant*_*th0 118 java performance if-statement switch-statement
担心我的网络应用程序的性能,我想知道哪个"if/else"或switch语句在性能方面更好?
Wav*_*ick 121
我完全同意过早优化是需要避免的.
但是,Java VM确实有特殊的字节码可以用于switch().
参见WM Spec(lookupswitch和tableswitch)
因此,如果代码是性能CPU图的一部分,那么可能会有一些性能提升.
Bal*_*usC 103
这是微观优化和过早优化,这是邪恶的.而是担心有问题的代码的可读性和可维护性.如果if/else胶合在一起的块数超过两个或其大小不可预测,那么您可能会高度考虑一个switch声明.
或者,您也可以获取多态性.首先创建一些界面:
public interface Action {
void execute(String input);
}
Run Code Online (Sandbox Code Playgroud)
并掌握所有实现Map.您可以静态或动态地执行此操作:
Map<String, Action> actions = new HashMap<String, Action>();
Run Code Online (Sandbox Code Playgroud)
最后替换if/else或switch通过类似的东西(留下无效的检查,如无效指针):
actions.get(name).execute(input);
Run Code Online (Sandbox Code Playgroud)
它可能比if/else或者微小switch,但代码至少可以更好地维护.
当您谈论Web应用程序时,您可以使用HttpServletRequest#getPathInfo()as操作键(最终编写一些代码以在循环中将pathinfo的最后部分分开,直到找到操作).你可以在这里找到类似的答案:
如果您一般担心Java EE Web应用程序的性能,那么您可能会发现本文也很有用.除了(微)优化原始Java代码之外,还有其他领域提供了更多的性能提升.
Joh*_*lla 50
if/else或switch很可能成为你性能问题的根源.如果您遇到性能问题,应首先进行性能分析分析,以确定慢点的位置.过早优化是万恶之源!
然而,有可能谈论switch与if/else与Java编译器优化的相对性能.首先请注意,在Java中,switch语句在非常有限的域上运行 - 整数.通常,您可以按如下方式查看switch语句:
switch (<condition>) {
case c_0: ...
case c_1: ...
...
case c_n: ...
default: ...
}
Run Code Online (Sandbox Code Playgroud)
where c_0,,c_1...和c_N是作为switch语句的目标<condition>的整数,并且必须解析为整数表达式.
如果这个集合是"密集的" - 即(max(c i)+ 1 - min(c i))/ n>α,其中0 <k <α<1,其中k大于某个经验值,a可以生成跳转表,这是非常高效的.
如果此集合不是非常密集,但是n> =β,则二叉搜索树可以在O(2*log(n))中找到目标,这仍然是有效的.
对于所有其他情况,switch语句与等效的if/else语句系列完全一样有效.α和β的精确值取决于许多因素,并由编译器的代码优化模块确定.
最后,当然,如果域<condition>不是整数,则switch语句完全没用.
Bit*_*lue 10
使用开关!
我讨厌维护if-else-blocks!做一个测试:
public class SpeedTestSwitch
{
private static void do1(int loop)
{
int temp = 0;
for (; loop > 0; --loop)
{
int r = (int) (Math.random() * 10);
switch (r)
{
case 0:
temp = 9;
break;
case 1:
temp = 8;
break;
case 2:
temp = 7;
break;
case 3:
temp = 6;
break;
case 4:
temp = 5;
break;
case 5:
temp = 4;
break;
case 6:
temp = 3;
break;
case 7:
temp = 2;
break;
case 8:
temp = 1;
break;
case 9:
temp = 0;
break;
}
}
System.out.println("ignore: " + temp);
}
private static void do2(int loop)
{
int temp = 0;
for (; loop > 0; --loop)
{
int r = (int) (Math.random() * 10);
if (r == 0)
temp = 9;
else
if (r == 1)
temp = 8;
else
if (r == 2)
temp = 7;
else
if (r == 3)
temp = 6;
else
if (r == 4)
temp = 5;
else
if (r == 5)
temp = 4;
else
if (r == 6)
temp = 3;
else
if (r == 7)
temp = 2;
else
if (r == 8)
temp = 1;
else
if (r == 9)
temp = 0;
}
System.out.println("ignore: " + temp);
}
public static void main(String[] args)
{
long time;
int loop = 1 * 100 * 1000 * 1000;
System.out.println("warming up...");
do1(loop / 100);
do2(loop / 100);
System.out.println("start");
// run 1
System.out.println("switch:");
time = System.currentTimeMillis();
do1(loop);
System.out.println(" -> time needed: " + (System.currentTimeMillis() - time));
// run 2
System.out.println("if/else:");
time = System.currentTimeMillis();
do2(loop);
System.out.println(" -> time needed: " + (System.currentTimeMillis() - time));
}
}
Run Code Online (Sandbox Code Playgroud)
我记得读过Java字节码中有两种Switch语句.(我认为它是'Java性能调优'一个是一个非常快速的实现,它使用switch语句的整数值来知道要执行的代码的偏移量.这将要求所有整数是连续的并且在明确定义的范围内我猜测使用Enum的所有值也会属于那个类别.
我同意许多其他海报...虽然这是非常热门的代码,但担心这个可能为时过早.
在我的测试中,更好的性能是Windows7 中的ENUM > MAP > SWITCH > IF/ELSE IF。
import java.util.HashMap;
import java.util.Map;
public class StringsInSwitch {
public static void main(String[] args) {
String doSomething = null;
//METHOD_1 : SWITCH
long start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
String input = "Hello World" + (i & 0xF);
switch (input) {
case "Hello World0":
doSomething = "Hello World0";
break;
case "Hello World1":
doSomething = "Hello World0";
break;
case "Hello World2":
doSomething = "Hello World0";
break;
case "Hello World3":
doSomething = "Hello World0";
break;
case "Hello World4":
doSomething = "Hello World0";
break;
case "Hello World5":
doSomething = "Hello World0";
break;
case "Hello World6":
doSomething = "Hello World0";
break;
case "Hello World7":
doSomething = "Hello World0";
break;
case "Hello World8":
doSomething = "Hello World0";
break;
case "Hello World9":
doSomething = "Hello World0";
break;
case "Hello World10":
doSomething = "Hello World0";
break;
case "Hello World11":
doSomething = "Hello World0";
break;
case "Hello World12":
doSomething = "Hello World0";
break;
case "Hello World13":
doSomething = "Hello World0";
break;
case "Hello World14":
doSomething = "Hello World0";
break;
case "Hello World15":
doSomething = "Hello World0";
break;
}
}
System.out.println("Time taken for String in Switch :"+ (System.currentTimeMillis() - start));
//METHOD_2 : IF/ELSE IF
start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
String input = "Hello World" + (i & 0xF);
if(input.equals("Hello World0")){
doSomething = "Hello World0";
} else if(input.equals("Hello World1")){
doSomething = "Hello World0";
} else if(input.equals("Hello World2")){
doSomething = "Hello World0";
} else if(input.equals("Hello World3")){
doSomething = "Hello World0";
} else if(input.equals("Hello World4")){
doSomething = "Hello World0";
} else if(input.equals("Hello World5")){
doSomething = "Hello World0";
} else if(input.equals("Hello World6")){
doSomething = "Hello World0";
} else if(input.equals("Hello World7")){
doSomething = "Hello World0";
} else if(input.equals("Hello World8")){
doSomething = "Hello World0";
} else if(input.equals("Hello World9")){
doSomething = "Hello World0";
} else if(input.equals("Hello World10")){
doSomething = "Hello World0";
} else if(input.equals("Hello World11")){
doSomething = "Hello World0";
} else if(input.equals("Hello World12")){
doSomething = "Hello World0";
} else if(input.equals("Hello World13")){
doSomething = "Hello World0";
} else if(input.equals("Hello World14")){
doSomething = "Hello World0";
} else if(input.equals("Hello World15")){
doSomething = "Hello World0";
}
}
System.out.println("Time taken for String in if/else if :"+ (System.currentTimeMillis() - start));
//METHOD_3 : MAP
//Create and build Map
Map<String, ExecutableClass> map = new HashMap<String, ExecutableClass>();
for (int i = 0; i <= 15; i++) {
String input = "Hello World" + (i & 0xF);
map.put(input, new ExecutableClass(){
public void execute(String doSomething){
doSomething = "Hello World0";
}
});
}
//Start test map
start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
String input = "Hello World" + (i & 0xF);
map.get(input).execute(doSomething);
}
System.out.println("Time taken for String in Map :"+ (System.currentTimeMillis() - start));
//METHOD_4 : ENUM (This doesn't use muliple string with space.)
start = System.currentTimeMillis();
for (int i = 0; i < 99999999; i++) {
String input = "HW" + (i & 0xF);
HelloWorld.valueOf(input).execute(doSomething);
}
System.out.println("Time taken for String in ENUM :"+ (System.currentTimeMillis() - start));
}
}
interface ExecutableClass
{
public void execute(String doSomething);
}
// Enum version
enum HelloWorld {
HW0("Hello World0"), HW1("Hello World1"), HW2("Hello World2"), HW3(
"Hello World3"), HW4("Hello World4"), HW5("Hello World5"), HW6(
"Hello World6"), HW7("Hello World7"), HW8("Hello World8"), HW9(
"Hello World9"), HW10("Hello World10"), HW11("Hello World11"), HW12(
"Hello World12"), HW13("Hello World13"), HW14("Hello World4"), HW15(
"Hello World15");
private String name = null;
private HelloWorld(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void execute(String doSomething){
doSomething = "Hello World0";
}
public static HelloWorld fromString(String input) {
for (HelloWorld hw : HelloWorld.values()) {
if (input.equals(hw.getName())) {
return hw;
}
}
return null;
}
}
//Enum version for betterment on coding format compare to interface ExecutableClass
enum HelloWorld1 {
HW0("Hello World0") {
public void execute(String doSomething){
doSomething = "Hello World0";
}
},
HW1("Hello World1"){
public void execute(String doSomething){
doSomething = "Hello World0";
}
};
private String name = null;
private HelloWorld1(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void execute(String doSomething){
// super call, nothing here
}
}
/*
* http://stackoverflow.com/questions/338206/why-cant-i-switch-on-a-string
* https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10
* http://forums.xkcd.com/viewtopic.php?f=11&t=33524
*/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
99657 次 |
| 最近记录: |