개발 As 공부/JAVA

BufferedReader VS Scanner 속도 차이

민킹 2025. 1. 2. 16:24

상황 요약

백준 4949번 문제를 풀고 난 후 다른 사용자들의 답변 확인 중에 내가 제출한 코드의 실행 시간이 유난히 돋보임. 같은 언어 (JAVA)를 사용했음에도 불구하고 내 답변의 실행 시간은 다른 사용자들의 두 배. 이미 몇 가지 코드를 보며 대부분 stack을 활용해 문제를 풀어낸 것을 알고 있음. 나와 풀이 방식이 별로 다르지는 않다. 그렇다면 차이가 무엇인가? 입/출력 방식이 눈에 띔. 나는 Scanner를 사용하여 입력 받고 있었고 다른 사용자들은 Buffer를 통한 입력을 받고 있었다. 짐작가는 원인을 찾아냈으면 테스트를 통한 결과를 보고 말아야만 직성이 풀리지 않는가. 그래서 아래와 같이 Scanner -> BufferedReader로 바꿔 답변을 제출해 봄. 실행 시간이 다른 사용자들과 비슷해졌다!

 

Scanner 사용 시

 

또한 내가 제출한 코드가 아닌 400ms를 초과한 다른 답변들을 확인 해 보니 전부 Scanner를 쓰고 있는 것으로 확인 되었다.

 

 

BufferedReader 사용 시

//        Scanner scanner = new Scanner(System.in);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

 

동일한 코드에 입력 부분만 바꿔주었을 뿐인데 메모리 사용량과 실행 시간이 확연히 차이가 나기 시작한다. (후에 출력 부분도 System.out.println -> BufferedWriter로 바꿔 주었고 시간은 244ms로 더 줄었다.)

 

 

끝내는 말

Scanner보다 BufferedReader의 성능이 더 좋다는 것은 이미 알고 있었지만 이번 기회를 통해 다시 각인이 되었다. 오랜만에 알고리즘 문제를 풀게 되었고 맞는 답변을 작성하는것을 우선으로 하자는 생각에 예전부터 익숙하게 사용해오던 Scanner를 사용하게 된 것이 이렇게 성능 차이를 두 눈으로 확인하게 만들어 주었다.

 

성능 차이의 원인을 살짝 검색해 보았더니 의외로 '버퍼'는 차이를 내는 큰 원인은 아니었던 것 같다. BufferedReader의 기본 버퍼 사이즈를 Scanner(1024KB)와 동일하게 맞춰 입력 테스트를 해 보니 의외로 별 차이를 보이지 않았다는 결과가 있었다. 그렇다면 진짜 원인은 무엇일까? 바로 '정규식'의 사용 여부라는 의견이 많다. Scanner는 입력 문자를 정규식을 통해 해석하는데 반하여 BufferedReader는 문자열 그대로 StringBuffer를 사용하여 저장하더라는 것이다.

 

얼마전에 Split과 StringTokenizer의 성능 차이를 비교해 본 적이 있는데 둘의 성능 차이 원인에도 '정규식'이 한 몫 했다. 정규식을 사용하게 되면 개발자 입장에서는 입력 값을 이리 저리 사용하기 편하지만 컴퓨터 입장은 반대인 것으로...