[사이드 프로젝트] 함수형 프로그래밍 익히기 With Java - Supplier

gimseonjin616·2022년 5월 11일
0

Supplier

Supplier는 직역하면 제공자라는 뜻으로 타 함수와 다르게 매개변수를 받지 않고 특정 값을 반환하는 get이라는 추상메서드가 존재한다.

사용 예시는 간단하다.

public class Main {
    public static void main(String[] args){

        Supplier<String> helloWorldSupplier = () -> "hello world";

        String result = helloWorldSupplier.get();

        System.out.println(result);

    }
}

위 처럼 Supplier로 구현하면 get() 추상메소드를 통해 return 값을 받아올 수 있다.

단순히 보면 그냥 "hello world"를 반환하는 함수를 만들거나 변수에 바로 넣으면 되는데 왜 귀찮게 Supplier를 사용하는 것일까??

실행 시기 결정 가능 - Lazy Evaluation

3초 후, random 값을 반환하는 함수를 구현했다고 하자, 입력된 카운트 수 만큼 random 값을 출력하되 짝수 count 일 때만 출력한다면 총 얼만큼의 시간이 걸릴까?

카운트를 5만큼 주면 0, 2, 4 일때만 출력되기 때문에 약 9 + @ 만큼의 시간이 걸릴 것이라고 추측할 수 있다.

그러나 실제 코드를 돌려보면 다르다.

public class NoSupplier {

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis();

        for(int i = 0; i < 5; i++){
            printRandom(getRandom(), i);
        }

        System.out.println((System.currentTimeMillis() - startTime)/1000 + "seconds");
    }

    public static double getRandom() throws InterruptedException {
        TimeUnit.SECONDS.sleep(3);
        return Math.random();
    }

    public static void printRandom(double d, int c){
        if(c % 2 == 0){
            System.out.println(d);
        }
    }
}

위처럼 구현 시, 함수가 실행되고 반환되는 결과값이 파라미터로 매핑된다. 즉 0,2,4 인 경우에만 random 값이 필요한데 실제로는 모든 count 값에 전부 실행이되서 성능이 악화된다.

반면 Supplier를 사용하면 상황이 바뀐다.

public class WithSupplier {

    public static void main(String[] args){
        long startTime = System.currentTimeMillis();

        for(int i = 0; i < 5; i++){
            printRandom(getRandom(), i);
        }

        System.out.println((System.currentTimeMillis() - startTime)/1000 + "seconds");
    }

    public static Supplier<Double> getRandom() {
        return () -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Math.random();
        };
    }

    public static void printRandom(Supplier<Double> d, int c){
        if(c % 2 == 0){
            System.out.println(d.get());
        }
    }
}

기존 Supplier를 사용하기 전에 15초 걸리던 로직이 사용하면 우리가 예측한대로 9초만에 계산된 것을 확인할 수 있다.

이처럼 함수 실행을 원하는 시점에 할 수 있도록 조절하는 것을 Lazy Evaluation이라고 하며 적절하게 사용할 시 높은 성능 향상을 가져올 수 있다.

profile
to be data engineer

0개의 댓글