c/c++パフォーマンス最適化--I/O最適化(上)

3217 ワード

この節ではI/O最適化について直接紹介したいと思っていますが、後でよく使われるI/O操作関数の特徴を紹介する必要があることを考えてみましょう.I/Oに関するライブラリ関数(C 99基準)について説明します
異なるオペレーティングシステムには異なるファイル管理方式があり、現行の主にFAT(fileallocation table)、FAT 32、NTFS(new technoly file system)、NWFS(netware file system)、UFS(unix file system)がある.もちろん、AFS(andrew filesystem)、DFS、Micorsoft DFS、NFS(net file system)、これらのファイルシステムのセキュリティメカニズムと属性には違いがあるので、I/O最適化を行うときは、使用するファイルシステムのタイプに注目してください.
第一に、フォーマット入出力関数のいくつかについて、formatのタイプがfprintf()、printf()、sprintf()、snprintf()、vfprintf()、vprintf()、vspprintf()、vsnprintf()などと一致しているかどうかを確認することに注意してください.
第二に、remove()、rename()、fopen()、freopen()のいくつかの関数を使用するときは、a、ファイル名と操作プロパティを指定すること、b、これらの操作はファイルの属性を変えることができて、ある変更は不可逆的で、必ず注意しなければなりません.fopenの場合、removeは使用できません.多重合併の場合は特に注意が必要です.マルチスレッド/マルチプロセスのリスク制御については、後述しますが、ここで説明します.
第三に、ファイルパスは標準化処理を推奨し、また要求に応じて相対パスと絶対パスを選択する.パッケージされたcanonicalize path name moduleを持っている会社がたくさんあります.新人なら、ベテランに聞いてみてください.ソフトウェアがリリースされるまで、パスに問題があることに気づかないでください.
第四:fopenが使用するときは、ファイルを作成するか、既存のファイルを開くかを知っておく必要があります.混同を避けるためにfopenでパッケージ(wrapper)を作った人もいます.例えば、ファイルを作成するためにcreat_fileでfopenをカプセル化するファイル作成機能は、私自身にとって、このようなwrapperはあまり好きではありません.もちろんこれは個人的な習慣です.とにかく自分の目的を知っておく必要があります.
第五:ファイル操作関数、戻り値がある場合は必ず戻り値をチェックし、ファイル操作結果があなたが望んでいることを確定します.
error_の使用Noファイル操作結果を解析する場合、マルチスレッドの場合は粒度制御に注意してください.特定のソリューションでは、マルチスレッドの書籍を参照できます.多かれ少なかれerrorの安全な使用方法について言及されています.no.
第六:fseek()でrewind()を置き換えます.理由は簡単です.rewindは戻り値がなく、セキュリティチェックができません.fseek(stream,0 L,SEEK_SET)は機能的にrewindと同じです.
第七:remove,rename操作の際,ファイルの状態がopenであるか否かを決定する.
第八:コードがデータ整合性に要求される場合、fflush()でバッファをリフレッシュしてください.
第九:setbufの代わりにsetvbufを使用するのは、同じ理由で前者がsetbuf(stream,buf)=setvbuf(stream,buf,_IOFBF,BUFSIZ)or setvbuf(stream,buf,_IONBF,BUFSIZ)
第十:text modeとbinary modeの違いを理解する.この2つのモードでfseekとungetcを使用する方法は異なります.読者自身でまとめてほしい
第十一:foefとferrorでファイルの終わりとファイルの操作エラーをチェックすることに慣れている
第12:getc()とputc()はマクロなので、境界効果があります.例えばchar *file_name;FILE *fptr;
  /*Initialize file_name */
  int c = getc(fptr = fopen(file_name,"r")); if (c == EOF) {   /*Handle error */ } // 。。 。 : int c; char *file_name; FILE *fptr;
  /*Initialize file_name */
  fptr= fopen(file_name, "r"); if (fptr == NULL) {   /*Handle error */ }
  c= getc(fptr); if (c == EOF) {   /*Handle error */ } : , , 。
C++ストリーム操作については後述するが、ここではCのみを紹介し、補足を歓迎する