문제 : Hello World!를 출력하시오
1. 그냥 System.out.println 해버리기
백준 알고리즘에서는 클래스 이름을 Main 으로 해줘야 컴파일 에러가 나지 않습니다.
일반적인 System.out.println 으로 풀이 하는 방법은 시간이 116ms 가 나옵니다.
print 메서드 안에 넣은 String 이 내용이 짧아서 시간이 작게 나왔지만,
내용이 조금만 길어지면 시간이 1초 이내로 못푸는 불상사가 나오게됩니다.
그래서 대부분 백준에서 코드 풀이하는 사람들은 String대신에 BufferedWriter 를 사용합니다.
2. BufferedWriter 사용하기
(BufferedWriter 설명보다는 flush() 메서드의 기능에 더 중점을 둔 글입니다.)
BufferedWriter 를 사용하면 자바에서는 120ms가 나오게 됩니다.
BufferedWriter 는 보통 try ~ catch 문을 사용해서 출력하면 되는데
내가 try catch 를 해버리니까 거기서 시간이 좀 걸린거 같습니다.
Input Output 예외처리는 throws 로 올려버려서 과정을 하나 줄이고,
변수도 OutputStreamWriter를 위한 변수를 하나 만들었었던 과정도 없애버리면
조금이나마 더 빠르고 간결한 코드 작성이 가능해집니다.
- flush() 를 사용하는 이유 (남아있는 데이터를 모두 출력시킨다.)
우선 flush() 메서드를 사용하지 않고 다시 제출 해보겠습니다.
시간이 124ms가 되었습니다. flush() 메서드를 사용하지 않아서 시간이 늘었습니다.
자바8 api docs 를 읽어봐도 뭔가 상세하게 적혀있진 않았습니다.
Stream 을 flush 해주는 그런 느낌으로 받아들여야 할 것 같은데요
flush는 flu(flow) + sh(throw) 의 느낌으로 받아들여야 하는 것 같습니다.
보통 물이라고 하면 물이 흘려버리고 흩뿌리는 느낌입니다.
어떠한 흐름이 흘러나오는 그런 느낌을 받으셨나요?
Stream 도 어떻게 보면 흐름이고, 여기서는 데이터의 흐름 정도로 생각할 수 있기 때문에
Stream 에서의 데이터를 흐르게 해서 흩뿌리는 느낌 정도로 이해하면 될 것 같습니다..
flush의 실제 역할은 이렇습니다.
flush() 는 Writer 내부에서 Overrides 가 됩니다.
파일을 Stream 으로 전송을 할 경우 I/O 횟수를 줄이기 위해 버퍼에 쌓았다가,
버퍼에 데이터가 쌓이면 한꺼번에 내보내는데요
이 때 버퍼 stream에 남아있는 데이터를 flush 로 강제로 내보내는 역할을 합니다.
그러니까 기본적인 출력스트림은 버퍼에 데이터가 가득차면 그때 데이터를 출력시키는데,
이 메서드는 저장된 데이터의 크기에 상관이 없이 바로 출력을 시켜준다는 뜻입니다.
flush 메서드를 사용하지 않아도 파일은 전송이 잘 되나 버퍼를 close 하기 전에 flush 를 해주는 것과,
버퍼를 close를 해 준 이후 close 메서드에서 자동으로 flushing 하는 것에는 속도차이가 납니다.
속도차이가 나는 이유는 솔직히 잘 모르겠습니다만...
제 견해입니다.
close 메서드는 stream을 닫아주는 역할을 하면서 제일 먼저 내부적으로 flush 를 해줍니다.
이때 stream 이 닫힌 이후에 write() 나 flush() 를 추가로 호출하면 IOException 이 발생하게 되는데요,
close를 하기 전에 flush를 하지 않는다면 내부적으로 IOException 을 한 번 더 걸러내는 작업을 해야 합니다.
BufferedWriter.class 의 close 메서드를 살펴본 결과입니다.
flush() 를 호출하는경우 flushBuffer()를 호출하고,
close()를 호출하는 경우 if문을 먼저 읽고 저기서 return이 되지 않으면 try문을 읽어서 flushBuffer() 호출하는 것 같습니다.
저도 사실 자바 생초보여서 자세히는 다루긴 어려워서 여기까지만 알아봅시다 ㅠ;
아무튼 저기서 알 수 있는 것은 먼저 flush()를 하고 close()를 하면 바로 if문에 걸려 return이 될 것이라는 것입니다.
그런데 flush() 없이 close()를 하게 되면 if문을 내부적으로 한 번 더 읽어들이고 조건에 맞지 않기 때문에 통과해서
try문을 읽어 들이고 flushBuffer() 를 호출해서 마침내 Stream이 닫히게 되는 것입니다.
이 차이가 속도차이를 내는 원인인 것 같습니다.
그렇기 때문에 결론적으로 말씀드리면 백준 알고리즘에서 BufferWriter 를 할 때
속도를 더 빠르게 출력하기 위해 flush() 메서드를 close() 메서드를 적용하기 전에 명시적으로 작성하는 것입니다.
자바 고수이신 분들 댓글로 제 글에 오류가 없는지 확인해주신다면 감사하겠습니다. 😅
'Java (국비지원 당시 공부했던 글) > Java 프로그래밍' 카테고리의 다른 글
[JDBC] JDBC 란 무엇인가 (자바에서 DB연결해서 코딩하기), JDBC API 참조 (0) | 2022.07.17 |
---|---|
[자바] - 백준 10718, 10171, 10172번 풀이 (0) | 2022.06.06 |
[자바] 무작위 숫자 생성 (2) - Random 클래스 (0) | 2022.04.26 |
[자바] 무작위 숫자 생성 (1) - Math.random() (0) | 2022.04.22 |
제어구조(control structure) (0) | 2022.04.15 |