본문 바로가기

Programing/JVM(Java, Kotlin)

System.out 의 성능?

마이그레이션을 위한 임시 코드로 로깅을 위해 System.out.println 을 사용했다.

Q. 예외상황이긴 하지만, 최대 size가 1000개일텐데, System.out.println 괜찮을까요?

여기에 세 고개가 더 붙여졌다.

Q2. 왜 "System.out.println 안 괜찮을까요?"
Q3. 성능?
Q4.어떤 성능이요?

지금은 절판된 자바 성능을 결정짓는 코딩 습관과 튜닝 이야기에도 11번 "로그는 반드시 필요한 내용만 찍자" 부분에서 System.out.print 사용에 관련된 내용이 있어서 내용의 요지는 이해했으나 상기 차원에서 검색을 해서 기록해 두었다.

 

  출처: Java - System.out effect on performance

관점1. println 은 synchronized 로 동기화가 되어 있어서 객체 헤더에 대한 잠김 오버헤드(locking overhead)가 있을 수 있다.

package java.io;

public class PrintStream extends FilterOutputStream
    implements Appendable, Closeable
{
    // ..
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

관점2. console에 출력은 커널 시간을 필요로 한다. 커널 시간은 CPU가 사용자 모드에서 수행되지 않는 것을 의미하기에 애플리케이션의 코드 대신 커널 코드에 대한 수행에 대한 부하가 늘 수 있다. (?)

 

관점3. 만약 사용하는 플랫폼이 비동기 I/O를 지원하지 않을 경우 busy wait들에 대해 CPU가 잠김이 발생할 수 있다.

 

 

그 아래 PrintWriter와 BufferedWriter 를 붙인 println과 비교를 해놓았을 때는 성능차이가 250%나 달라졌다는 실험 내용도 있었다.

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();

vs

System.out.println(yourString);

Test results (on Macbook Pro, with SSD reading&writing using same disk):

  • data-output-to-system-out > output.txt => 1min32sec
  • data-written-to-file-in-java => 37sec
  • data-written-to-buffered-writer-stdout > output.txt => 36sec