U E D R , A S I H C RSS

Java/Mode Selection Performance Test

Servlet —„œ, ˜Š” Switch - Case “ฑ งŽ€ ถ„๊ธฐฅผ •˜Š” ฐฉ•— Œ€•œ ””žธ & ผฌจผŠค ๊€ —„œ˜ ๊ตฌ๊ฒฝ.

1. if-else

Œ€๊ฐ• ‹คŒ˜ ฝ”“œ Šคƒ€ผผ๊ฒƒ‹ค.
~cpp 
public class IfElse {
    public void printPerformance(String[] modeExecute) {
        long start;
        long end;
        start = System.currentTimeMillis();
        for (int i = 0; i < ModeChoicePerformanceTest.LOOPING_COUNT; i++) {
            executeIfElse(modeExecute);
        }
        end = System.currentTimeMillis();
        System.out.println("if - else elapsed time :" + (end - start) + "ms ");
    }

    private void executeIfElse(String[] modeExecute) {
        for (int i = 0; i < modeExecute.length; i++) {
            executeWithIfElse(modeExecute[i]);
        }
    }

    public void executeWithIfElse(String mode) {
        if (mode.equals("One")) {
            doOne(1);
        } else if (mode.equals("Two")) {
            doTwo(1);
        } else if (mode.equals("Three")) {
            doThree(1);
        } else if (mode.equals("Four")) {
            doFour(1);
        } else if (mode.equals("Five")) {
            doFive(1);
        } else {
            doDefault(1);
        }
    }


    public void doOne(int i) {
        i = 10;
    }

    public void doTwo(int i) {
        i = 10;
    }

    public void doThree(int i) {
        i = 10;
    }

    public void doFour(int i) {
        i = 10;
    }

    public void doFive(int i) {
        i = 10;
    }

    public void doDefault(int i) {
        i = 100;
    }
}
 ฐฉ•€ ผ‹จ †„ƒœผก  ๊ฐ€žฅ น ‹ค. •˜€งŒ, •œŽธœผกœ
Seminar:WhySwitchStatementsAreBadSmell— ๊ฑธฆฌ€ •Š„๊นŒ? ๊ทผฐ.. ๊ทธ— Œ€•œ ฐ˜ก œผกœ “ค–˜คŠ”๊ฒƒ '๊ฑ mode ถ„๊ธฐ€กœ •ž—„œ˜ Switch-Statement —„œ˜ ˜ˆ™€Š” ‹คฅธ ƒ™•„‹ˆƒ. –ฐจ”ผ ถ„๊ธฐ ›„—” ๊ทธƒ•‹น €ถ„ ‹ค–‰˜๊ณ  ‹ค.' ผ๊ณ  ง• ๊ฒƒ‹ค. ๊ธ€Œ”. ๊ฒ ‹ค.
•œŽธœผกœ А๊€Š” ๊ฒƒœผกœŠ”, switch กœ ถ„๊ธฐฅผ ‚˜ˆŒ mode string ๊ณผ ›น parameter ™€˜ ค‘ณต žˆ„ ๊ฒƒผŠ”   ธ‹ค. ๊ทธฆฌ๊ณ  •˜‚˜˜ mode ๊ฐ€ Š˜–‚ •Œงˆ‹ค •‹น method ๊ฐ€ Š˜–‚˜๊ณ , mode string  Š˜–‚˜๊ณ , if-else ๊ตฌฌธ ฃผšฑ ๊ธธ–ง„‹คŠ”   žˆ‹ค. €๊ธˆ€ ฉ”†Œ“œกœ ถ”ถœ„ •†“€ ƒ™€งŒ, งŒผ  € €ถ„ ฉ”†Œ“œกœ ถ”ถœ •ˆ˜–žˆ‹ค? ๊ทธ๊ฑ ‹จ •œงˆ”” ฐ–— • ง —†‹ค. (‹จ,  € …ผฌธ„ •„Š” ‚ฌžŒ— •œ•„œ) GotoStatementConsideredHarmful.

‘ฒˆงธ - Method reflection

~cpp 

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

public class MethodFullReflection {
    public void printPerformance(String[] modeExecute) throws InvocationTargetException, IllegalAccessException {
        long start;
        long end;
        start = System.currentTimeMillis();
        for (int i = 0; i < ModeChoicePerformanceTest.LOOPING_COUNT; i++) {
            executeReflection(modeExecute);
        }
        end = System.currentTimeMillis();
        System.out.println("elapsed time :" + (end - start) + "ms ");

    }

    private void executeReflection(String[] modeExecute) throws InvocationTargetException, IllegalAccessException {
        for (int i = 0; i < modeExecute.length; i++) {
            Method method = null;
            try {
                method = this.getClass().getMethod("do" + modeExecute[i], new Class[]{int.class});
                method.invoke(this, new Object[]{new Integer(1)});
            } catch (NoSuchMethodException e) {
                this.doDefault(1);
            } catch (SecurityException e) {
                e.printStackTrace();  //To change body of catch statement use Options | File Templates.
            }
        }
    }

    private void doDefault(int i) {
        i = 100;
    }

    public void doOne(int i) {
        i = 10;
    }

    public void doTwo(int i) {
        i = 10;
    }

    public void doThree(int i) {
        i = 10;
    }

    public void doFour(int i) {
        i = 10;
    }

    public void doFive(int i) {
        i = 10;
    }

}
žฅ  : MODE ๊ฐ€ ถ”๊ฐ€ •Œงˆ‹ค doXXX ‹œผกœ ฆ„„  ••ฃผ๊ณ  ฅผ ‹ค–‰•˜ œ‹ค. กฐ๊ฑ ถ„๊ธฐ €ถ„˜ ฝ”“œ๊ฐ€ ฆ๊ฐ€˜€ •Š๊ณ , •‹น Mode ๊ฐ€ ถ”๊ฐ€ •Œงˆ‹ค ฉ”†Œ“œ •˜‚˜งŒ ถ”๊ฐ€•ฃผ œ‹ค.
‹จ  : žฐ”—„œŠ” Method Reflection & Invoke ๊ฐ€ —„ฒญ Аฆฌ‹ค.; †„Š” ฐ‘˜๊บผ ฐธกฐ.

„ธฒˆงธ. œ„˜ ฐฉ•„ ™„•œ ฐฉ•‹ค. ฐ”กœ ผข…˜ Table Lookup.

~cpp 

import java.util.HashMap;
import java.util.Map;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

/**
 * User: Administrator Date: 2003. 7. 12. Time: ˜ค „ 12:48:38
 */
public class MethodTableLookupReflection {
    public void printPerformance(String[] modeExecute) throws InvocationTargetException, IllegalAccessException {
        long start;
        long end;
        start = System.currentTimeMillis();
        initReflectionMap(modeExecute);
        end = System.currentTimeMillis();
        System.out.println("reflection with method initialize table elapsed time :" + (end - start) + "ms ");

        start = System.currentTimeMillis();
        for (int i = 0; i < ModeChoicePerformanceTest.LOOPING_COUNT; i++) {
            executeReflectionWithMapping(modeExecute);
        }
        end = System.currentTimeMillis();
        System.out.println("reflection with method elapsed time :" + (end - start) + "ms ");

    }

    private static Map methodMap;


    private void executeReflectionWithMapping(String[] modeExecute) throws InvocationTargetException, IllegalAccessException {
        for (int i = 0; i < modeExecute.length; i++) {
            Method method = (Method) methodMap.get(modeExecute[i]);
            if (method != null)
                method.invoke(this, new Object[]{new Integer(1)});
            else
                doDefault(1);
        }
    }

    private void initReflectionMap(String[] methodNames) {
        methodMap = new HashMap();
        for (int i = 0; i < methodNames.length; i++) {
            try {
                methodMap.put(methodNames[i], this.getClass().getMethod("do" + methodNames[i], new Class[]{int.class}));
            } catch (NoSuchMethodException e) {
            } catch (SecurityException e) {
            }
        }

    }

    private void doDefault(int i) {
        i = 100;
    }

    public void doOne(int i) {
        i = 10;
    }

    public void doTwo(int i) {
        i = 10;
    }

    public void doThree(int i) {
        i = 10;
    }

    public void doFour(int i) {
        i = 10;
    }

    public void doFive(int i) {
        i = 10;
    }
}
 ฐฉ•€ œ„˜ ฐฉ•๊ณผ ๊ฐ™€ žฅ „ €‹ˆ„œ ผฌจผŠคฅผ ๊ฑฐ˜ 10ฐฐ๊ฐ€Ÿ‰ –ฅƒ‹œ‚จ‹ค.

„คฒˆงธ. Inner Class — Œ€• Command Pattern ˜ ‚ฌšฉ.

~cpp 

import java.util.Map;
import java.util.HashMap;

/**
 * User: Administrator Date: 2003. 7. 12. Time: ˜ค „ 12:57:7
 */
public class InterfaceTableLookup {
    protected Map modeMap = new HashMap();

    public void printPerformance(String[] modeExecute) {
        long start;
        long end;
        start = System.currentTimeMillis();
        initModeMap();
        end = System.currentTimeMillis();
        System.out.println("interface table lookup init table elapsed time :" + (end - start) + "ms ");

        start = System.currentTimeMillis();
        for (int i = 0; i < ModeChoicePerformanceTest.LOOPING_COUNT; i++) {
            executeInnerclassMapping(modeExecute);
        }
        end = System.currentTimeMillis();
        System.out.println("interface table lookup elapsed time :" + (end - start) + "ms ");


    }

    private void executeInnerclassMapping(String[] modeExecute) {
        for (int i = 0; i < modeExecute.length; i++) {
            executeMode(modeExecute[i]);
         }
    }

    private void executeMode(String s) {
        IMode mode = (IMode) modeMap.get(s);
        if (mode == null) doDefault(1);
        else mode.execute(1);
    }

    public class ExOne implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public  class ExTwo implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExThree implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExFour implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExFive implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    private void initModeMap() {
        modeMap.put("One", new ExOne());
        modeMap.put("Two", new ExTwo());
        modeMap.put("Three", new ExThree());
        modeMap.put("Four", new ExFour());
        modeMap.put("Five", new ExFive());
    }
}
 ฐฉ•€ initModeMap —„œ งคฒˆ Mode— Œ€•œ “ฑก„ •ค˜••œ‹ค. ผฌจผŠคŠ” Method Reflection ‹ค ›จ”ฌ น ‹ค.

งˆ€ง‰ ฐฉ• - interface & reflection

œ„˜ ฐฉ•— initModeMap „ reflection œผกœ ฒ˜ฆฌ•œ ๊ฒƒ‹ค.
~cpp 
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * User: Administrator Date: 2003. 7. 12. Time: ˜ค „ 1:2:16
 */
public class InterfaceTableLookupReflection {
    public void printPerformance(String[] modeExecute) throws NoSuchMethodException, InstantiationException, ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        long start;
        long end;
        start = System.currentTimeMillis();
        initModeMapWithReflection(modeExecute);
        end = System.currentTimeMillis();
        System.out.println("interface reflection & table lookup init able elapsed time :" + (end - start) + "ms ");

        start = System.currentTimeMillis();
        for (int i = 0; i < ModeChoicePerformanceTest.LOOPING_COUNT; i++) {
            executeInnerclassMapping(modeExecute);
        }
        end = System.currentTimeMillis();
        System.out.println("interface reflection & table lookup elapsed time :" + (end - start) + "ms ");

    }

    private void executeInnerclassMapping(String[] modeExecute) {
        for (int i = 0; i < modeExecute.length; i++) {
            executeMode(modeExecute[i]);
         }
    }

    private void executeMode(String s) {
        IMode mode = (IMode) modeMap.get(s);
        if (mode == null) doDefault(1);
        else mode.execute(1);
    }

    protected Map modeMap = new HashMap();
    public final static String modeClassHeader = "Ex";
    String expectedClassNameHeader = this.getClass().getName() + "$" + modeClassHeader;

    private void initModeMapWithReflection(String[] modeExecute) throws InstantiationException, InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        Class[] consParamClasses = new Class[]{this.getClass()};
        Object[] consParams = new Object[]{this};


        Class[] inners = this.getClass().getClasses();
        for (int i=0;i<inners.length;i++) {
            if (inners[i].getName().startsWith(expectedClassNameHeader)) {
                Constructor innerCons = inners[i].getDeclaredConstructor(consParamClasses);
                modeMap.put(modeExecute[i], innerCons.newInstance(consParams));
            }
        }
    }

    public void doDefault(int i) {
        i = 100;
    }

    public class ExOne implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public  class ExTwo implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExThree implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExFour implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }

    public class ExFive implements IMode {
        public void execute(int i) {
            i = 10;
        }
    }
}
 ฐฉ•€ Mode ถ”๊ฐ€‹œ ๊ทธƒฅ ExModeName ‹œผกœ ถ”๊ฐ€•ฃผ œ‹ค. ๊ทธŸฌ„œ Mode กฐ๊ฑ ถ„๊ธฐ €ถ„ €•˜€ •ŠŠ”‹ค. Reflectionœผกœ table lookup ฑ„šฐŠ” €ถ„‚˜ Mode กฐ๊ฑ ถ„๊ธฐ €ถ„„ •„— ƒœ„ ž˜Šคกœ ถ”ถœ•  ˆ˜ žˆ‹ค. ผฌจผŠค—„œŠ” ˜™กœ •ž—„œ ˆ˜™œผกœ map „ ฑ„šฐŠ” ฐฉ•๊ณผ ๊ฐ™‹ค. œ —ฐ„ฑ๊ณผ ผฌจผŠค ‘๊ฐ€€๊ฐ€   ˆžˆ –šธ–€Š” ฐฉ•‹ค.


๊ฑ œ„˜ …ŒŠคŠธ“ค„ •œฒˆ— ‹ค–‰‹œ‚ค๊ธฐ œ„•œ runner class.
~cpp 
import java.lang.reflect.InvocationTargetException;

/*
  ‰๊ฐ€•˜ คŠ” กฐ๊ฑ“ค :
  1. •‹น method ˜ naming œผกœ reflection call.
  2. switch - case กœ mode ๊ตฌถ„.
  3. interface & class - command pattern ˜ ๊ตฌ˜„.

  ‰๊ฐ€š”†Œ“ค
  1. •‹น ฝ”“œ ž‘„ฑŒ€น„ Š˜–‚˜Š” ฐ˜ณต ž‘—…“ค
  2. performance
  3. maintance
*/
public class ModeChoicePerformanceTest {
    public static final int LOOPING_COUNT = 1000000;

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, InstantiationException {
        String[] modeExecute = new String[]{"One", "Two", "Three", "Four", "Five", "hugu"};

        new IfElse().printPerformance(modeExecute);
        new MethodFullReflection().printPerformance(modeExecute);
        new MethodTableLookupReflection().printPerformance(modeExecute);
        new InterfaceTableLookup().printPerformance(modeExecute);
        new InterfaceTableLookupReflection().printPerformance(modeExecute);
    }
}

๊ฒฐ๊ณผ

~cpp 
if - else elapsed time :611ms 
elapsed time :61889ms 
reflection with method initialize table elapsed time :0ms 
reflection with method elapsed time :6459ms 
interface table lookup init table elapsed time :10ms 
interface table lookup elapsed time :741ms 
interface reflection & table lookup init able elapsed time :10ms 
interface reflection & table lookup elapsed time :731ms 
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:33
Processing time 0.0175 sec