본문 바로가기
프로그래밍 공부/C++ 프로그래밍

[C++ 기초] 표준 입출력 스트림(Stream)의 동기화 및 입출력 속도의 최적화

by 섬댕이 2023. 5. 13.

 

표준 입출력 스트림, 스트림 객체

표준 입출력 스트림이란, 컴퓨터 프로그램과 입출력 장치(키보드나 마우스 / 모니터 등) 사이에 입출력 데이터를 바이트의 흐름의 형태로 전송하기 위해 미리 연결되어 있는 통로이다. C와 C++에는 이러한 입출력 스트림과, 해당 스트림을 관리하기 위한 스트림 객체가 존재한다.

 

  • C: stdin(입력), stdout(출력), stderr(에러)
  • C++: cin(입력), cout(출력), cerr(에러), clog(로그) (+ wcin, wcout, wcerr, wclog)

 

기본적으로 C와 C++의 표준 입출력 스트림 사이에는 각각 입출력 연산 후 동기화를 수행하도록 설정되어있고, C의 표준 입출력 스트림이 사용하는 버퍼(buffer)를 C++의 표준 입출력 스트림들도 같이 사용한다.

 

입력과 출력의 빈도가 압도적으로 높은 프로그램의 경우는 자연스럽게 입/출력 속도가 중요한 비중을 차지하게 되는데, C++ 표준 입출력 스트림을 이용하는 프로그램이면 스트림 객체를 이용해 표준 입출력 스트림을 최적화하여 빠른 실행 결과를 확보할 수 있다(단, 주의점도 존재한다).

 


 

코딩 문제 풀이 등의 사이트에서 C++ 코드를 기준으로, 아래의 코드를 이용하는 케이스를 종종 확인할 수 있다.

 

// using namespace std; 를 통해 std:: 생략 가능
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);

 

std::ios::sync_with_stdio()

C의 표준 스트림과 C++의 표준 스트림이 각각 입출력 연산 후 동기화를 수행할 지 여부를 설정하는 기능을 한다. 동기화를 해제(false를 인수로 사용)하면 각 표준 스트림이 독립적인 버퍼를 사용하여 작동하므로 입출력 속도가 향상된다.

* 주의점) C-style, C++-style의 입출력을 혼용 불가능, 멀티쓰레딩 환경에서 레이스 컨디션 발생 가능성 존재.

 

std::cin.tie(), std::cout.tie()

C++ 표준 입출력 스트림들 사이의 동기화 여부를 설정하는 기능을 한다. 기본적으로는 tie 되어있으며 이로 인해 다른 스트림에서 작업 요청을 하게 되면 현재 스트림의 작업 내용을 flush하는 기능을 수행하게 된다. untie를 할 경우 입출력이 빈번하게 바뀌어 일어나는 경우 flush를 수시로 수행하지 않아 실행 속도를 향상시킬 수 있다.

* 주의점) 입출력 명령이 연이어 존재할 때, 어떤 명령이 먼저 실행될지를 장담할 수 없다.

 


 

위의 입출력 실행 속도 최적화는 실제로는 주로 코딩 문제 풀이 사이트에서나 빈번하게 사용되는 것 같은데 단순히 입출력 실행 속도를 무조건 향상시키기 위해서 무차별적으로 사용하기보다는, 주의점을 명확하게 인지한 상태에서 꼭 필요할 때만 정확하게 사용하는 것이 중요할 것 같다는 생각이다(아직 실무 경험은 없지만, 특히나 멀티쓰레딩 컴파일을 주로 하게 되는 실무에서는 절대로 사용하면 안될 것 같은 느낌이다. 코딩 문제 사이트와 같이 싱글쓰레딩 환경인 것이 명확하고, 필요할 때에만 제한적으로 쓰는 습관을 들이는 게 좋을 것 같다).

 


 

* 해당 카테고리의 글은 Microsoft 공식 홈페이지의 기술 문서 페이지와 Stephan Prata의 저서 C++ 기초 플러스 (6판, 번역본) 서적 및 기타 구글링을 통한 정보 수집 등을 토대로 개인적으로 요약/정리해 본 글입니다. 만약 잘못 정리된 내용이 있다면, 댓글이나 이메일로 공유해주시면 수정하도록 하겠습니다.

댓글