빠른 입력과 출력을 위해 BufferedReader와 BufferedWriter라는 것을 사용할 때가 있다. Input Data를 몇십만, 몇백만건씩 받을 때가 있는데, 기존에 사용하던 Scanner 나 System.out.print를 사용하면 시간초과가 발생할 수 있다. 이 사실을 기반으로 좀 더 코드를 살펴보기 위해 본 포스팅을 작성해보았다.
먼저, 각 메서드의 시스템 흐름도이다.
Scanner와 System.out.println의 시스템 흐름도 | BufferedReader와 BufferedWriter의 시스템 흐름도 |
그림과 같이 중간에 과정이 추가되었는데 어떻게 연산 속도가 더 빠를 수 있는지 궁금해졌다. 이 부분에 대해 다양한 포스팅을 뒤적거렸다. 핵심은 디스크 I/O와 문맥 교환, 입출력은 생각보다 느리다는 생각부터 출발한다. 예로 키보드를 입력할 때마다 프로그램으로 전달이 된다면 오버헤드가 크게 발생한다. 따라서, 키보드 입력을 끝낸 뒤에 한 번에 전달되는 것이 훨씬 빠를 것이다. 마트에서 물건을 살 때 물건마다 진열대에서 계산대로 옮기는 것보다, 쇼핑카트에 담았다가 한 번에 계산대로 가져가는게 더 빠르다는 비유를 들 수 있을 것이다.
하지만 BufferedReader에도 몇 가지 단점이 있다. 단점은 다음과 같다.
- IOException의 예외처리가 필수적이다.
- 입력받은 모든 데이터가 String으로 반환된다.
- 줄마다 입력받아서, 따로 split하여 데이터를 처리해주어야 한다.
- 숫자형식으로 받기 위해서는 형변환이 필요하다.
Input Data에 1 2 3이 들어왔을 때 Scanner의 nextInt()로 받으면, [1, 2, 3]을 차례대로 받을 수 있다. 하지만 BufferedReader의 readLine()으로 받으면, "1 2 3"이라는 문자열 자체로 받으며, split(' ')로 띄어쓰기를 구분하여 Integer.parseInt() 과정이 필요해진다.
위와 같은 지식을 기반으로 코드를 작성해보았다.
package Step3;
import java.io.*; // 1. import는 java.io.*로 한다. (Scanner는 java.util 클래스이다.)
public class BufferHap {
public static void main(String[] args) throws IOException { // 2. main함수 우측에 throws IOException을 통해 예외를 처리한다.
// 메소드 선언부에 throws를 명시하면, 해당 메소드 내에서 exception이 발생하는 경우 해당 메소드를 호출한 곳에서 예외가 발생한다.
// 3. BufferedReader, BufferedWriter를 선언한다.
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 4. n을 입력받고, n만큼 loop를 돈다.
int n = Integer.parseInt(bf.readLine());
for (int i=0; i < n; i++){
String s = bf.readLine(); // 4-1. 해당 줄 전체를 String으로 입력받아, 스페이스로 구분하여 형변환하여 덧셈을 수행한다.
int a = Integer.parseInt(s.split(" ")[0]);
int b = Integer.parseInt(s.split(" ")[1]);
bw.write(a+b+"\n"); // 5. BufferedWriter에 써준다.
}
bw.flush();// 6. Buffer를 전송하고 Buffer를 비워준다.
}
}
*여기서, bw.write()는 버퍼에 쓰는것이지, 화면에 출력되는 것이 아니다. 화면에 출력하는 역할은 bw.flush()가 수행한다. bw.flush()는 출력이 필요할 때 한 번만 수행해주면 된다. 만약 for문 안에 bw.flush()를 쓰면, 버퍼에 쓰고 바로 출력하므로 System.out.print와 다를바가 없다.고 한다.
* Scanner vs Buffer
'Programming > Algorithm' 카테고리의 다른 글
[백준] 2434번 : 별 찍기 - 1 (0) | 2021.10.27 |
---|---|
[백준] 3052번 : 나머지 (Java) (0) | 2021.10.27 |
선형 리스트 (Linear List) (0) | 2021.09.27 |
알고리즘의 개념 (0) | 2021.09.27 |
자료구조의 개념 (0) | 2021.09.27 |