반응형

백준 같은 알고리즘 사이트에서 Java를 통해 문제를 풀다보면 유독 다른 언어에 비해 실행시간이 길다는 것을 알 수 있습니다.

최근 많은 알고리즘 사이트에서 각 언어마다 다른 기준으로 메모리나 시간을 평가하고 있긴 하지만, 그래도 여전히 자바를 사용해 문제를 푸는 입장에선 불안할 수 밖에 없습니다.

그렇다면 답이 없는 것일까요?

고민을 하다가 문득 입출력에서 속도를 높일 수 있진 않을까 하는 생각이 들었고, 서치를 해보니 역시나 Scanner와 System.out.println 메소드보다 더 빠른 방법을 찾았습니다.

 

Scanner 보다 더 빠른 BufferedReader

긴 말 않고 바로 예제를 살펴보겠습니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        int n = Integer.parseInt(br.readLine());
        
        br.close();
    }
}

 먼저, BufferedReader는 java.io 패키지에 포함되어 있습니다. 그렇기 때문에 사용하고자 한다면 import 해줘야 합니다.

사용 방법은 간단합니다. Scanner를 사용할 때 생성자에 파라미터로 System.in을 넣어줬던 것처럼, BufferedReader도 마찬가지인데, 단 BufferedReader의 생성자는 InputStreamReader를 파라미터로 갖기 때문에 InputStreamReader 인스턴스를 생성하고 그의 생성자에 System.in을 넣어주면 되겠습니다.

 

그리고 BufferedReader 클래스에서 제공하는 readLine()을 통해 한 줄 단위로 읽을 수 있습니다. Scanner의 nextLine()과 같은 역할이라고 보면 되겠습니다.

BufferedReader의 경우 Scanner와 달리 타입 별로 파싱해주는 메소드가 따로 제공되지 않기 때문에 만약 숫자로 읽고 싶은 경우에는 위 예제처럼 Integer.parseInt() 메소드를 통해 별도로 변환 해줘야합니다.

이리저리 테스트해 본 결과 BufferedReader를 사용할 경우 Scanner를 사용했을 때보다 약 3~5배 정도 빠른 것으로 확인했습니다.

 

System.out.println 보다 빠른 BufferedWriter

BufferedWriter의 경우 입력이 아닌 출력이라는 부분을 제외하고선 앞서 설명한 BufferedReader와크게 다르지 않기 때문에 간단하게 설명하겠습니다.

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Main {
    
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        bw.write("example");
        bw.write("\n");
        
        bw.close();
    }
}

 BufferedWriter 클래스는 입력이 아닌 출력이기 때문에 생성자의 파라미터로 OutputStreamWriter와 그 안에 System.out을 넘겨주면 되겠습니다.

그리고 출력은 write() 메소드를 사용하면 되는데, println()과 달리 개행문자(줄바꿈)를 자동으로 처리 해주지 않기 때문에 필요한 경우 직접 입력해줘야 합니다.

 

그리고 BufferedReader와 BufferedWriter 모두 공통적으로 IOException을 발생시킬 수 있기 때문에 그에 대한 처리도 반드시 해줘야 합니다. 위의 예제에서는 throws 처리 했습니다.

 

마무리

자바를 메인 언어로 사용하는 입장에서 "자바는 느린 언어이기 때문에 알고리즘 풀이에 적합하지 않다"는 편견으로부터 발버둥 치고싶었습니다. 알고리즘 문제 풀이에서 언어는 논리를 구현해내는 도구일 뿐 C나 C++ 등의 언어를 사용한다 해서 더 좋지 못한 알고리즘이 느린 언어의 좋은 알고리즘 보다 좋은 결과를 낼 것이라 생각하지 않습니다.

계속해서 자바로 빠른 결과를 내는 것에 관심을 두고, 더 좋은 방법이 발견되거든 블로그에 공유하도록 하겠습니다.

반응형
반응형