-
입력을 받았을 때, 직접 input stream에서 데이터를 읽어오기Dev. Diary/Memo 2023. 8. 28. 18:34
오랜만에 BOJ 알고리즘 문제(수 나누기 게임(27172))를 풀었다. 풀고 나서 Java로 푼 사람들의 시간을 확인해보았는데, 나의 풀이의 절반 정도 걸리는 풀이들이 보였다. 평소에는 크게 관심이 없기도 했고, 엄청 큰 차이인가 싶지만, 갑자기 궁금해져서 어떤 부분에서 차이가 생기는지 알아보았다.
문제를 푸는 아이디어는, 아래에 '에라토스테네스의 체'라는 힌트가 있었어서, 크게 다르지 않았다. 나의 코드와 가장 차이가 나는 부분은 입력을 받는 부분이었다. 나는 여태까지 BufferedReader 클래스를 사용해서 입력을 처리했었는데, 가장 빠른 풀이를 제출하신 분(roeyr)은 아래의 코드를 이용하여 입력을 받고 있었다.public static int readInt() throws IOException { int val = 0; // 입력받을 값을 기록하는 변수 int c = System.in.read(); // read() 메서드는 다음으로 오는 byte 값을 int 변수로 반환하고, input stream이 끝나면 -1을 반환한다. while (c <= ' ') { // 빈칸이 입력되면 다음 값을 읽는다.(' '은 int로 32) c = System.in.read(); } boolean flag = (c == '-'); // 음수를 읽기 위해 사용되는 flag 변수('-'는 int로 45) if (flag) c = System.in.read(); // '-'로 시작하면 다음 byte 값을 받아놓는다. do { val = 10 * val + c - 48; // c가 숫자인 동안 값을 읽어오고, 읽어오면서 10진수로 val에 새로 저장한다. } while ((c = System.in.read()) >= 48 && c <= 57); // '0', '9'는 각각 int로 48, 57 if (flag) // 음수이면 -부호를 붙여서 반환 return -val; return val; }
뤼튼에 잠깐 검색해보았는데, BufferedReader는 Buffer를 사용하여 데이터를 읽는데 위의 readInt() 메서드는 Buffer를 사용하지 않고 직접 스트림에서 데이터를 읽어오기 때문에 빠르다고 하는데, 아직 정확히 알고 있는 내용은 아니라서 좀 더 알아봐야 할 것 같다. 일단 '스트림에서 데이터를 읽어오는 것이 Buffer를 사용하는 것보다 빠르다'는 것에서 시작해보면 좋을 것 같다.
어쨌든 빠르면 좋은 것이니 앞으로 입력을 받을 때는 위의 코드를 사용해서 받도록 코드를 짜는 습관을 들여봐야할 것 같다. 그리고 저 코드를 내가 짰던 코드에 적용해보았을 때 시간이 줄긴 했지만, 그럼에도 가장 빠른 풀이보다는 시간이 조금 더 걸렸고, 메모리도 조금 더 많이 쓰였다. 아이디어의 세세한 차이때문이겠지만, 정확히 어떤 부분때문인지도 궁금한데, 나중에 알게 되면 다시 적어봐야겠다.'Dev. Diary > Memo' 카테고리의 다른 글
Comparable 인터페이스를 구현할 때 비교자(Comparator) 이용하기 (0) 2023.09.27 requireNonNull() 메서드 관련 메모 (0) 2023.09.22 오토 박싱, 언박싱 조심! (0) 2023.09.20 객체의 일관성에 관한 메모 (0) 2023.09.19 정적 팩토리 메서드를 알아보다가 느낀 점 (0) 2023.09.17