백준 1655문제를 JAVA로 풀다가 계속해서 시간초과가 떠서 심히 빡이 쳤다.
내가 짠 C++ 코드를 그대로 JAVA로 Porting을 했음에도 시간초과가 떴다.
결국 원인은 System.out.print(max_heap.peek())에 있었다.
소스 코드(시간초과)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PriorityQueue<Integer> max_heap = new PriorityQueue<>(Collections.reverseOrder());
PriorityQueue<Integer> min_heap = new PriorityQueue<>();
int n = Integer.parseInt(br.readLine());;
for( int x = 0; x < n; x++){
int num = Integer.parseInt(br.readLine());
if(max_heap.isEmpty())
max_heap.offer(num);
else if(max_heap.size() == min_heap.size())
max_heap.offer(num);
else
min_heap.offer(num);
if(!min_heap.isEmpty() && max_heap.peek() > min_heap.peek() ){
int a = max_heap.poll();
int b= min_heap.poll();
max_heap.offer(b);
min_heap.offer(a);
}
System.out.println(max_heap.peek()); // 실행 속도 많이 잡아 먹음.
}
System.out.println은 Java 개발에서 가장 기본이 되는 함수이며 쓰기 편리하고 구현도 간단하다.
하지만 System.out.println 방식의 출력은 시스템 리소스를 필요 이상으로 잡아먹는다는 한계가 존재한다.
시간과 리소스를 고려한다는 측면에서 우리는 빠른 입출력 방식인 BufferedWriter를 사용할 수 있다.
public static void main(String[] args) throws Exception {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// BufferedWriter 객체를 이용하여 출력합니다.
bw.write("Hello World!");
// write한다고 해서 바로바로 출력되지 않습니다.
// 직접 출력 stream에 반영되는 것이 아니라 성능을 위해 buffer에 저장해두었다가
// BufferedWriter가 flush되거나 close되었을 때 한번에 출력 stream에 반영하기 때문입니다.
bw.flush();
// close는 stream을 닫아버리기 때문에 계속 출력하고자 한다면 flush 사용합니다.
// bw.close();
// 출력내용에 줄바꿈이 필요하다면 newLine 함수를 사용합니다.
bw.newLine();
// 혹은 \n을 출력값의 앞이나 뒤에 넣어줍니다.
bw.write("new line\n");
bw.write("new line2");
bw.close();
StringBuilder를 사용하는 이유도 System.out.println(문자열)의 속도가 그리 좋지 않기 때문이다.
JAVA의 String은 문자열의 수정이라는 것이 불가능하다.
개발자에게는 수정한 것처럼 보이지만, 메모리 내부에서는 수정된 문자열 객체가 동적으로 할당이 된 것 뿐이다.
예를 들어 for문 10000번을 돌면서 10000줄의 문자열을 출력해야한다고 하면
System.out.println("정답")은 만번의 String을 선언하고 메모리를 잡아 먹고, heap 영역에 객체를 위한 공간 할
당을 받는데에 매우 큰 시간 비용이 들어 간다.
System.out.println("출력값") * n번
>가장 느림
BufferedWriter.write("출력값") * n번
BufferedWirter.flush()
>빠름
StringBuilder.append("출력값") * n번
System.out.println(StringBuilder.toString())
>조금 더 빠름
System.out.println에 대해서는 동고님이 잘 정리해두신 내용이 있어 link 남겨드립니다. 참고하세요.
System.out.println에 관한 고찰
자바 개발 시, 가장 먼저 배우는게 바로 System.out.println이다.아마 System.out.prinln("Hello World!")를 안써본 사람은 없을 것이다.그럼에도 불구하고 자바 개발 시 지양해야하는 것중 하나가 바로 System.out
donggov.tistory.com
아래 링크도 정리가 잘 돼 있으므로 참조
https://cantcoding.tistory.com/38
StringBuilder를 쓰는 이유
StringBuilder란. API를 살펴보면 첫줄에 A mutable sequence of characters 라고 써있다. String은 immutable 한 객체로 값을 수정하면 새로운 객체를 만들어 내서 메모리를 잡아먹고 시간도 잡아먹게된다. 하지만
cantcoding.tistory.com
자바에서 주로 사용하는 기능들의 속도 측정 및 비교(TimeMills와 nanoTime의 차이 / System.out.println()
목차1. TimeMillis 와 nanoTime 의 차이2. System.out.println() 의 문제점3. String 과 StringBuffer 의 차이4. 기본 자료구조 - Set & List & Map 1. TimeMillis 와 nanoTime 의 차이 2. System.out.println() 의 문제점 3. String 과 StringB
drsggg.tistory.com
'프로그래밍 언어 (プログラミング言語) > JAVA' 카테고리의 다른 글
Comparable, Compartor 인터페이스 (0) | 2023.01.11 |
---|---|
JAVA의 정렬 (0) | 2023.01.04 |
Equal(), HashCode() in JAVA (0) | 2023.01.01 |
JAVA에서의 동기화 기법(모니터 etc) (0) | 2022.12.23 |
자바에서의 Priority_Queue (0) | 2022.12.18 |