I am wondering if there any performance different between a large switch statement and several small switch statements.
Large switch statement with hundreds of cases.
switch(quest){
case 1: quest1(); break;
case 2: quest2(); break;
.
.
.
case 196: quest196(); break;
case 197: quest197(); break;
.
.
.
}
or several smaller switch statement with 30 cases each.
if (quest <= 30) {
switch (quest) {
case 1: quest1(); break;
case 2: quest2(); break;
case 3: quest3(); break;
.
.
case 30: quest30(); break;
default:
return;
}
} else if (quest <= 60) {
switch (quest) {
case 31: quest31(); break;
case 32: quest32(); break;
case 33: quest33(); break;
.
.
.
case 60: quest60(); break;
default:
return;
}
}
.
.
.
Also, I know reflection will be a lot easier to code, but will that cause a large overhead?
something like this.
try {
Method method =Logic.class.getMethod("quest"+quest);
method.invoke(this);
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thanks in advance.
The difference between a large switch
and a chain of if
/ then
/ else
statements that include smaller switch
is that a single switch
will find the code to execute in a single lookup, while a chain of conditionals may need several individual checks before arriving at the switch
statement of interest. Once the switch
statement is found, it takes roughly the same time to do a dispatch, almost no matter how many case
labels there are. A single switch
statement is also more readable, so I would prefer it to a chain of conditionals.
Although reflection does have an overhead, it is not terrible, so if your questNNN
methods are not extremely fast, the overhead of reflection is not going to matter much. You could even speed it up by preparing an array of Method
objects, and populate it upfront to avoid the Logic.class.getMethod("quest"+quest)
calls at the time when you dispatch the call.
Finally, you could create an array of Runnable
objects, and encapsulate calls of questNNN
inside them:
Runnable[] dispatch = new Runnable[] {
new Runnable() { public void run() { quest0(); } }
, new Runnable() { public void run() { quest1(); } }
, new Runnable() { public void run() { quest2(); } }
, new Runnable() { public void run() { quest3(); } }
, new Runnable() { public void run() { quest4(); } }
...
, new Runnable() { public void run() { quest59(); } }
, new Runnable() { public void run() { quest60(); } }
};
Now you can call dispatch[NNN].run()
to call your questNNN
method.
If you really want to optimize do it for the programmers that will come after you. Use a proper structure that will make it obviously optimal for speed while patently clear and simple.
interface Quest {
void quest();
}
static Set<Quest> allQuests = new HashSet<>();
enum MontyPythonQuests implements Quest {
MakeMeAShrubbery {
@Override
public void quest() {
System.out.println("Build me a SHRUBBERY!!!!!");
}
},
SeekTheHolyGrail {
@Override
public void quest() {
System.out.println("Brave Sir Basil ran away!");
}
};
@Override
public void quest() {
// Simplistic default implementation just prints the name of the enum.
System.out.println(this.name());
}
MontyPythonQuests() {
// All quests are added to the list.
allQuests.add(this);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.