본문 바로가기
코딩테스트/문제풀이 팁

Stream, 되도록이면 사용하지 말자

by asdft 2024. 2. 26.

https://school.programmers.co.kr/learn/courses/30/lessons/12941

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

위 문제를 풀면서 아래 기존코드와 같이 Arrays.sort를 이용해서 내림차순을 하기 위해 Stream을 이용해서 int타입을 Integer 타입 배열로 박싱하는 코드를 구현했다.

 

하지만 이 코드는 정확선 테스트에서는 문제가 없었지만, 효울성 테스트를 통과하지 못했다.

 

기존코드

import java.util.*;
class Solution
{
    public int solution(int []A, int []B)
    {
        int total = 0;
        Arrays.sort(A);

        Integer[] Btemp = Arrays.stream(B).boxed().toArray(Integer[]::new);	// Arrays.sort를 이용한 내림차순은 int형으로 불가
        Arrays.sort(Btemp,Collections.reverseOrder());

        for(int i=0;i<A.length;i++){
            total = total + A[i]*Btemp[i];
        }

        return total;
    }
}

 

https://brorica.tistory.com/entry/java-stream

 

java stream이 for-loop보다 느린 이유

수정 이력 2022.12.27 맞춤법 수정 및 참조 문제 항목 추가 서론 프로그래머스에서 다른 사람들의 코드를 보면 stream을 사용한 코드들을 종종 보는데 정석적인 방식에 비해 몇 배 느린데도 숏 코딩+

brorica.tistory.com

 위의 사이트의 결론은 이렇다

결론
1. Stream은 나온지 얼마 안 된 기능이기 때문에, 내부 최적화가 기존에 비해 부족하다.
2. 많은 element에 대해 접근이 많은 상황에선 array나 collection가 좋다.
3. collection의 경우 간접적으로 접근하기 때문에, stream보다 빠르긴 해도 array만큼 빠르진 않다.
4. 한 element에 대해 많은 연산이 필요한 경우 stream이 유리하다.

 

한 element가 아닌 모든 element를 돌면서 쓰기에는 Stream이 적절하지 않다는 이야기를 하고 있었다.

그래서 아래와 같이 래퍼 클래스 타입인 배열을 새로 하나 만들어 이 안에 for-loop을 통해서 값을 하나씩 넣어준 후, 내림차순 정렬하는 코드로 수정했다.

 

그러니 정확도와 효율성 테스트에서 모두 통과하는것을 확인할 수 있었다.

변경코드

import java.util.*;
class Solution
{
    public int solution(int []A, int []B)
    {
        int total = 0;
        Integer[] Btemp = new Integer[B.length];
                
        // Collections.sort()를 위해 Wrapper클래스 배열에 저장.
        for(int i=0;i<B.length;i++){
            Btemp[i] = B[i];
        }
        // A 배열은 오름차순 정렬.
        Arrays.sort(A);
        // Btemp 배열은 내림차순 정렬.
        Arrays.sort(Btemp,Collections.reverseOrder());

        for(int i=0;i<A.length;i++){
            total = total + A[i]*Btemp[i];
        }

        return total;
    }
}