Justin의 개발 로그

조건부 연기 실행(Conditional Diferred Execution)

아래 코드에서 getMessage 메서드는 1000번 호출된다.

public class CDETest {

    private StopWatch sw;
    private String methodName;
    private boolean useLog = false;

    private CDETest() {
        sw = new StopWatch();
    }

    @BeforeEach
    void startStopWatch() {
        sw.start();
    }

    @AfterEach
    void endStopWatch() {
        sw.stop();

        System.out.println(methodName + " running time : " + sw.getTotalTimeMillis() + " ms");
    }

    @Test
    void 단순실행테스트() {
        methodName = "단순 반복 실행";
        String logMessage;

        for(int i = 0; i < 1_000; i ++) {
            logOut(useLog, getMessage(methodName));
        }
    }

    String getMessage(String methodName) {
        // 10ms이 걸리는 로직이 있다고 가정함
        try {
            Thread.sleep(2L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return methodName + " 실행시간 : " + System.currentTimeMillis() + " 에러 발생했습니다.";
    }

    void logOut(boolean useLog, String message) {
        if(useLog) System.out.println(message);
    }

}

 

이를 람다의 메서드 참조로 변경하는 것 만으로도 불필요한 메서드 호출을 방지해서 비약적인 성능 개선을 얻을 수 있다.

    @Test
    void 조건부연기실행() {    //conditional diferred execution
        methodName = "조건부 연기 실행";
        String logMessage;

        for(int i = 0; i < 1_000; i ++) {
            logOut(useLog, () -> getMessage(methodName));

        }
    }

    void logOut(boolean useLog, Supplier<String> f) {
        if (useLog) System.out.println(f.get());
    }

 

실행 어라운드 패턴(Execute Around Pattern)

전체 코드 대부분이 반복되고, 일부만 다른 코드가 있다면 중복되는 코드를 재사용하는 실행 어라운드 패턴을 사용해서 코드를 간결하게 만들 수 있다. 

public class ExecuteAroundPattern {

    @Test
    void ReadFileOneLineTest() throws IOException {
        BufferedReader br = new BufferedReader(
                new FileReader("src/main/resources/data.txt")
        );

        String contents = br.readLine();

        System.out.println("한줄 : " + contents);
    }

    @Test
    void ReadFileTwoLinesTest() throws IOException {
        BufferedReader br = new BufferedReader(
                new FileReader("src/main/resources/data.txt")
        );

        String contents = br.readLine();
        contents += br.readLine();

        System.out.println("두줄 : " + contents);
    }

}
    @FunctionalInterface
    private interface BufferedReaderProcessor {
        String process(BufferedReader b) throws IOException;
    }

    private String processFile(BufferedReaderProcessor p) throws IOException {
        BufferedReader br = new BufferedReader(
                new FileReader("src/main/resources/data.txt")
        );

        return p.process(br);
    }

    BufferedReaderProcessor readOneLine = (BufferedReader b) -> b.readLine();
    BufferedReaderProcessor readTwoLines = (BufferedReader b) -> b.readLine() + b.readLine();

    @Test
    void LambdaTest() throws IOException {
        String result = processFile(readOneLine);
        System.out.println("한줄 : " + result);

        result = processFile(readTwoLines);
        System.out.println("두줄 : " + result);
    }
profile

Justin의 개발 로그

@라이프노트

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!