CS

[CS] I/O 속도 개선을 위한 ios_base::sync_with_stdio(false), cin.tie(NULL), '\n'

SeungbeomKim 2023. 8. 15. 15:15

백준에서 간단한 stack 문제를 푸는 도중 발생한 시간 초과 문제입니다. 모든 테스트케이스를 고려했었고, 100% 확신을 한 상태에서 제출을 했는데 다음과 같은 issue가 발생했습니다.

설마설마하고 ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) 코드를 넣었는데 정답 처리가 되었습니다.

그래서 이러한 사례가 많았는데, 막연하게 시간초과 방지를 위해 코드를 달아주는 것 외에는 정확히 모르고 있었습니다. 그래서 이 코드들에 대해 무엇이고 어떠한 상황에 사용하는지 알아보려고 합니다.

 

  •  ios_base::sync_with_stdio(false): C/C++ 표준 스트림 간 동기화 비활성화 처리
    • 장점
      • 일반적으로 C++ 표준 스트림(cin + cout)은 C 표준 스트림(stdin + stdout)과 동기화가 됩니다. 그래서 동기화 옵션을 false로 설정해 주면 C++ 스트림이 자체적으로 독립적인 버퍼를 가질 수 있어 입/출력 속도를 향상할 수 있습니다.
      • 더불어 동기화된 C++ 버퍼는 thread-safe이기 때문에, 입/출력 결과를 보장할 수 있게 됩니다. 
    •  주의사항
      • single-thread 환경에서만 위의 성능들을 보장할 수 있습니다. 
      • C의 스트림을 비활성화 해주었기에 scanf/printf/puts/getchar/putchar(C의 입/출력 방식)를 사용해서는 안됩니다.
  • cin.tie(NULL)
    • 다른 스트림의 I/O 작업 전에 한 스트림이 자동으로 플러시(버퍼를 비우는 작업) 되도록 합니다(모든 출력이 표시됨)
    • cin/cout은 입력을 기다리기 전에 출력이 표시되도록 하는 데 유용할 수 있지만, 경우에 따라 성능 향상을 위해 자동 플러시를 비활성화해야 할 필요가 있습니다. 
    • 즉, 입력에 대한 출력을 한꺼번에 보고 싶을때 cin.tie(NULL)(자동 플러시 비활성화)를 걸어주면 됩니다. 
    • 하지만, 입출력의 순서를 보장받을 수 없게 됩니다. 
  • cout.tie(NULL)
    • cout 스트림도 마찬가지로 cin 스트림에 연결됩니다. 
    • cin을 이용하여 출력 작업을 수행하면 출력 작업이 발생하기 전에 존재했던 cin 스트림이 플러시 됩니다.
    • 이 옵션을 사용하게 되면 이러한 cin 스트림의 자동 플러시를 비활성화하게 됩니다.
  • endl -> '\n'
    • endl은 개행뿐만 아니라, 출력 버퍼까지 플러시 해줍니다. 
    • 매번 endl을 사용하게 되면 불필요하게 출력 버퍼를 비우게 되어 성능 저하가 발생합니다. 
    • 그래서 출력 버퍼를 명시적으로 비워줘야 하는 특별한 상황이 아니라면, 출력 버퍼까지 플러시 해주는 endl 대신 '\n'를 사용해야 합니다.

<참고자료>

https://stackoverflow.com/questions/31162367/significance-of-ios-basesync-with-stdiofalse-cin-tienull

 

Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);

What is the significance of including ios_base::sync_with_stdio(false); cin.tie(NULL); in C++ programs? In my tests, it speeds up the execution time, but is there a test case I should be worried...

stackoverflow.com

  https://velog.io/@gogori6565/BOJ-cin.tieNULL%EA%B3%BC-iosbasesyncwithstdiofalse

 

[BOJ/C++] cin.tie(NULL)과 ios_base::sync_with_stdio(false) 그리고 endl...

알고리즘 문제 풀면서 시간을 줄이는 방법들

velog.io