0

fprintfまたはfwrite. _ これが実装/プラットフォームに依存する機能である可能性があることを理解しています。私が興味を持っているのは、Windows、Linux、または Mac OS X などの最新の一般的なプラットフォームで少なくとも効率的に実装できると期待できるかどうかです。

私の知る限り、通常、I/O ルーチンのバッファリングは 2 つのレベルで行われます。

  1. ライブラリ レベル: これは、C 標準ライブラリ、または Java SDK ( BufferedOutputStream) などです。
  2. OS レベル: 最新のプラットフォームは、I/O 操作をキャッシュ/バッファリングします。

私の質問は#2ではなく# 1に関するものです(私はそれがすでに真実であることを知っています)。言い換えれば、最新のすべてのプラットフォームの C 標準ライブラリの実装でバッファリングを利用できると期待できますか?

そうでない場合は、手動でバッファを作成し(巧妙に選択されたサイズで)、オーバーフロー時にそれをフラッシュすることが問題の良い解決策ですか?

結論


setbufやのような関数を指摘してくれた皆さんに感謝しますsetvbuf。これらは、私の質問に答えるために探していた正確な証拠です。有用な抜粋:

ファイルが対話型デバイスを参照していないことがわかっている場合、すべてのファイルはデフォルトで割り当てられたバッファー ( full buffered ) で開かれます。この関数は、特定のメモリ ブロックをバッファとして使用するように設定するか、ストリームのバッファリングを無効にするために使用できます。

デフォルトのストリームは、インタラクティブなデバイスを参照していないことがわかっstdinstdoutいる場合、デフォルトで完全にバッファリングされます。それ以外の場合は、システムとライブラリの実装に応じて、デフォルトで行バッファーまたは非バッファーのいずれかになります。同じことが にも当てはまりstderrます。これは、デフォルトで常にライン バッファーまたは非バッファーのいずれかです。

4

4 に答える 4

3

ほとんどの場合、stdio ルーチンのバッファリングは、問題のオペレーティング システムの典型的なブロック サイズと一致するように調整されています。これは、デフォルトのケースで I/O 操作の数を最適化するために行われます。もちろん、setbuf()/setvbuf()ルーチンでいつでも変更できます。

特別なことをしている場合を除き、デフォルトのバッファリングに固執する必要があります。これは、OS でほぼ最適であることを確信できるためです (典型的なシナリオの場合)。

それを正当化する唯一のケースは、stdio ライブラリを使用して、それに対応していない I/O チャネルとやり取りしたい場合です。この場合、バッファリングを完全に無効にすることができます。しかし、私はこれのケースをあまり頻繁に見ることができません。

于 2013-10-31T21:21:07.470 に答える
1

@Davidが言ったように、(両方のレベルで)賢明なバッファリングが期待できます。

ただし、はフォーマット文字列を解釈するため、fprintfとの間には大きな違いがある可能性があります。それをスタックサンプリングすると、double を文字列などに変換する時間のかなりの割合を見つけることができます。fwritefprintf

于 2013-10-31T21:12:42.510 に答える
1

C IO ライブラリを使用すると、(アプリケーション内で、OS が行う前に) バッファリングが行われる方法を制御できますsetvbuf。何も指定しない場合、標準では、「開いたときに、ストリームがインタラクティブなデバイスを参照していないstdinと判断できる場合にのみ、ストリームが完全にバッファリングされる」ことが要求されます。それが非インタラクティブなデバイスに向けられていることを検出できた場合。stdoutstderr

于 2013-10-31T21:29:37.160 に答える
1

最新のシステムでは、標準 I/O が十分にバッファリングされていると考えて間違いありません。

于 2013-10-31T21:09:03.533 に答える