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.0166 sec