[JAVA] 빠른 입출력: BufferedReader, StringTokenizer
계기
백준 알고리즘 문제를 풀던 도중 생소한 문제를 만났다. 15552번인데, 단순한 덧셈 계산기 문제이지만 제한시간이 아주 짧았다.
그래서 문제에 써져있는 힌트를 참고하여 BuffedReader와 BufferedWriter를 이용하여 제출해보았다.
사실 이대로 사용법만 익히고 사용해도 되지만, 왜 Scanner는 안되고 BufferedReader는 되는건지 이유가 궁금해져서 알아보았다.
BufferedReader ( vs. Scanner )
BufferedReader | Scanner | |
자료형 | String | String, int, long, float, double... |
버퍼 크기 | 8KB | 1KB |
Buffering | O | X |
성능 | 빠르다 | 상대적으로 느리다 |
입력 구분자 | 개행문자 | 공백, 개행문자 등 |
BufferedReader는 문자 입력 스트림에서 문자를 읽기 위한 버퍼를 제공한다.
input을 버퍼에 입력했다가, 한번에 전송한다.
텍스트를 효율적으로 읽을 수 있도록 설계되었으며, readLine() 메서드로 한 줄씩 읽을 수 있다.
하지만 단점으로, 문자열(String)밖에 읽지 못하기 때문에 따로 정수형으로 변환해주어야 한다.
BufferedWriter도 원리가 같고, println()보다 더 빠르다.
반면 Scanner는 String, int, long, float, double 등 여러 자료형을 읽을 수 있으며, BufferedReader에 비해 적은 버퍼를 차지하기 때문에 간단한 입출력의 경우는 Scanner를 활용하는 편이 좋다. 또한 입력이 즉시 전달되는 방식이다.
두 방식의 차이를 예로 들자면,
BufferedReader는 쓰레기를 쓰레기통에 모았다가 처리하는 방식이고, Scanner는 쓰레기를 바로바로 처리하는 방식이다.
StringTokenizer ( vs. split )
BufferedReader는 입력 구분자가 개행문자밖에 없기 때문에, 다른 구분자를 이용해 문자열을 분리하고 싶다면 StringTokenizer 또는 split()메서드를 사용해야 한다.
StringTokenizer의 사용 방법은 다음과 같다.
StringTokenizer st = new StringTokenizer(문자열, 구분자);
StringTokenizer는 구분자를 기준으로 문자열을 단순히 분리만 한다. 사용이 빠르고 메모리 사용량이 적지만, 정규 표현식을 지원하지 않으며 복잡한 분리 작업에는 적합하지 않다.
하지만 split() 메서드는 정규 표현식을 사용하여 문자열을 분리할 수 있다. 복잡하고 다양한 방식으로 문자열을 나눌수 있다는 장점이 있다. 하지만 StringTokenizer에 비해 비교적 느리다.