-
(Java)Scanner vs BufferedReaderJava & Kotlin 2021. 2. 4. 16:38반응형
오늘은 Scanner과 BufferedReader에 대해서 작성하려고 합니다.
사용자로부터 콘솔에 어떤 값을 입력 받은 후 출력하는 대표적인 클래스들 입니다. 하지만 이 두개가 다르다는 것을 알고 계셨나요?
알고리즘 문제를 풀다 보면 Scanner 클래스를 이용해서 단순히 사용자로부터 입력 받은 값을 출력하면 될 것 같은데, 시간초과로 문제가 틀리는 경우가 있습니다. 이런 경우에는 BufferedReader라는 클래스가 있다는 것조차 모를 때는 정말 해결하기 어렵습니다. 왜냐하면 Scanner클래스를 사용했을 때의 속도에 대해서는 고려하지 않았기 때문입니다.
Scanner vs BufferedReader
Java 11 API의 설명을 참고합니다.
Scanner는 "간단하게 기본형과 String 타입을 정규표현식을 사용해서 파싱(Parse) 할 수 있다"라고 합니다. BufferedReader는 "사용자가 입력한 문자 스트림을 읽는(read) 것"이라고 합니다.
여기서 차이를가 느껴지시나요? 'parse'와 'read'의 차이 입니다. 여기서 Parse는 사용자가 입력한 텍스트를 token 단위로 잘라서, 특정한 형태로 반환하는 것 입니다. 하지만 Read는 사용자가 입력한 데이터를 덩어리 채로 그대로 읽어들이는 겁니다.
즉 Scanner.nextInt / nextLine 등등 여러가지 타입으로 반환을 하는 반면에, BufferedReader는 오직 String 형태로 읽어드리게 됩니다.
하지만 이게 어떻게 속도 차이를 가져오는 것일까요?
BufferedReader/BufferedWriter의 동작 방식
BufferedReader가 어떻게 동작하는지 알 필요가 있습니다.
Scanner는 위에서 말한대로 사용자가 입력한 데이터를 토큰 단위로 잘라서 그때그때 입출력을 하는 방식 입니다. 하지만 BufferedReader/BufferedWriter는 버퍼에 데이터가 가득차거나 개행이 될 때까지 기다린 후 입출력을 하는 방식 입니다. 그렇기 때문에 Buffered 형제는 String 형식으로 덩어리채로 입출력이 가능합니다.
하지만 버퍼에 저장을 했다가 보내는게 더 느릴 것 같은데 왜 더 빠를까요?
CPU를 고려해야 합니다. 문자가 입력될 때마다 CPU가 동작해서 하나하나 입출력을 하는 것 보다, 버퍼에 어느정도 쌓아두고 버퍼가 가득차거나 개행이 일어날 때마다 덩어리로 입출력 하는 것이 훨씬 효율적이고 빠릅니다.
하지만 Buffered 형제에게도 단점이 있습니다.
기본으로 지정된 버퍼의 크기가 다릅니다. Scanner는 1024 chars(1KB), Buffered는 8192 chars(8KB) 입니다. 즉 데이터가 얼마나 입력될지도 모르지만, 일단 큰 단위의 메모리를 잡아먹게 됩니다.
또한 String 형식으로만 입출력이 가능하므로, 다른 타입으로 변환하고자 할 때는 추가적인 코드가 필요합니다.
반응형'Java & Kotlin' 카테고리의 다른 글
(Java)Comparator 인터페이스 / compare 메소드 (0) 2021.03.04 (Java)ArrayList vs LinkedList 시간 복잡도 (0) 2021.02.22 (Java)Math.max vs 삼항연산자 (0) 2021.01.30 [Java]2차원 배열이란? (0) 2020.09.02 Firefox Java Coding Style (0) 2020.06.13