정보

파일의 Flush는 되도록 적게 하자

3년 전 쯤에 후배의 과제를 구경한 적이 있다. 코드 내 알고리즘 치곤 너무 느려서 한번 디버깅을 도와줬는데, 문제의 원인은 파일 저장 작업에서 flush 함수를 너무 많이 호출한 것. 거의 한 단어당 한 번씩 호출한 것이나 다름이 없는 정도로 매우 많이 호출했었다.

flush를 할 때마다 느려지는 원인은 바로 파일 입출력 기능에 있다. 주 기억 장치, 보조 기억 장치할것 없이 대부분의 장치는 쓰기 작업이 읽기 작업에 비해 느리다. 특히나 보조 기억 장치는 그것이 더한 편이다. 그 느린 보조 기억 장치의 쓰기 기능 중에서도 HDD의 쓰기 기능은 단연 톱으로 느리다. 물론 SSD나 USB 메모리의 기반이 되는 플래시 메모리 자체도 느리지만(기본적으로 HDD보다 느림) SSD는 내부적으로 플래시 메모리를 RAID로 묶어서 속도가 나오는 편. 따라서 SSD에 파일 쓰기 작업을 할 때 flush를 하면 그래도 속도가 많이 빠르다.

하드웨어적인 쓰기 기능 결함도 있지만 이와 연관된 소프트웨어적 결함도 있는데, flush를 할 때 동기 작업을 수행한다는 점이다. flush를 한다는 것은 곧 주 기억 장치에 작성했던 데이터를 보조 기억 장치로 보내고 주 기억 장치에 작성했던 데이터를 비운다는 것인데, 이 과정에서 flush가 동작하고 있으면서 flush를 완료하기 전에 데이터를 쓰게 되면 문제가 발생할 수 있다. 따라서 보통은 flush는 동기적으로 작업을 수행하며, 따라서 소프트웨어는 이에 속도를 맞춰서 동작한다. 물론 C#은 특정 버전부터(기억하기론 async-await이 추가된 5.0부터다) Flush 함수의 비동기 버전을 지원하지만 모든 언어가 이를 지원하진 않는다. 게다가 이를 공식적으로 지원하지 않는 언어나 플랫폼에서 어설프게 직접 비동기 기능을 작성한다면 문제가 발생할 소지도 있다.

Flush 많이 한다고 좋지 않다. 오히려 HDD의 경우 디스크 돌아가는 일이 늘어나고, SSD나 플래시 메모리의 경우 셀 수명이 단축될 수 있는 위험성도 존재한다. 물론 flush를 지속적으로 수행하면서 파일에 쓰기 작업을 하면 오류가 나서 프로그램이 종료가 돼도 그때까지 작성했던 데이터는 파일에 남는다는 장점은 있지만 쓰다가 만 파일이 얼마나 유용할지는 모르겠다.

Flush를 할거면 두 가지 중에 하나다. 청크 당 한 번 또는 파일 쓰기 마지막에 한 번 하자. 청크 당 한 번이면 그나마 쓰기 작업한 것이 유용하기 때문에 중간에 오류가 나도 사용이 가능한 데이터가 뽑힌다. 중간에 오류날 일도 없고, 어떻게 파일을 쓰든 오류 나서 프로그램이 꺼지면 파일도 날아간다고 봐야 되는 경우엔 중간중간 flush 쓴다고 좋은 것도 아니다. 웬만하면 flush는 자제하자.

광고

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중