一个大的switch语句还是几个小的switch语句?

时间:2014-07-29 23:57:06

标签: java switch-statement

我想知道大型switch语句和几个小型switch语句之间是否存在性能差异。

包含数百个案例的大型switch语句。

switch(quest){
            case 1: quest1(); break;
            case 2: quest2(); break;
            .
            .
            .
            case 196: quest196(); break;
            case 197: quest197(); break;
            .
            .
            .
        }

或几个较小的switch语句,每个30个案例。

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;
        }
    } 
  .
  .
  .

另外,我知道反射将更容易编码,但这会导致很大的开销吗?

像这样的东西。

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();
        }

提前致谢。

2 个答案:

答案 0 :(得分:2)

包含较小switch的大型ifthen / else / switch个语句链之间的区别在于{{1}将找到要在单个查找中执行的代码,而条件链可能需要在到达感兴趣的switch语句之前进行多次单独检查。找到switch语句后,执行调度所需的时间大致相同,几乎无论有多少switch个标签。单个case语句也更具可读性,因此我更倾向于一系列条件语。

虽然反射确实有开销,但并不可怕,所以如果你的switch方法不是非常快,那么反射的开销并不重要。你甚至可以通过准备一组questNNN个对象来加速它,并在你发出呼叫时预先填充它以避免Method个呼叫。

最后,您可以创建一个Logic.class.getMethod("quest"+quest)个对象数组,并在其中封装Runnable的调用:

questNNN

现在,您可以致电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(); } } }; 来调用dispatch[NNN].run()方法。

答案 1 :(得分:1)

如果你真的想要为你之后的程序员做优化。使用合适的结构,使其明显优于速度,同时显而易见,简单明了。

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);
    }
}