n個の整数の長さの整数のリストを含むファイルをループしながら、fscanf()で配列をフィードしようとしています。mallocおよび/または潜在的にreallocを使用する必要があるようです。mallocコマンドにはかなりの実行時間がかかるため、割り当てを超過するのが最善だと聞きました。誰かがこの目的を達成するための構成要素を理解するのを手伝ってくれませんか?
免責事項:私はCを初めて使用します。
いいえ、あなたが聞いたことは誤解を招くものです(少なくとも私にとっては)。malloc
は単なる関数であり、通常は高速な関数です。
malloc
malloc
このゲームで簡単に勝てると考えるのは非現実的です。これがあなたの質問に答えない場合は申し訳ありませんが(これはかなり一般的でした)、簡単に実装できる(スプーン)最適化がないことを理解する必要があります。
ファイルの読み取りは、メモリの割り当てよりもはるかに遅くなります。
ファイル全体を読んで、必要な全体の数を調べてから、malloc()を一度に実行することをお勧めします。
malloc(sizeof(int)* n)
時期尚早の最適化はすべての悪の根源です(グーグルそれ)。
とは言うものの、目前のタスクに合理的/一般的であると思われる量を割り当て、再割り当てが必要な場合は常にそれを2倍にします。この戦略を打ち負かすのはかなり難しいです。
特定のケースでは、mallocによって問題が発生することはありません。fscanfの実行時間は、mallocのオーバーヘッドよりも何倍も遅く、無料です。ただし、アプリの高性能領域に追加される可能性があります。これらの領域には、malloc()のオーバーヘッドと戦うことができる以外の方法があります。たとえば、memプールや固定サイズのアロケータなどです。しかし、始めたばかりのときは、パフォーマンスのオーバーヘッドについて心配する必要はほとんどありません。
内部データ構造を維持するために各割り当てにいくらかのオーバーヘッドを追加することに注意してくださいmalloc()
(一般的な実装では少なくとも4バイト)。したがって、整数が4バイトの長さの場合、malloc()
整数ごとにaを実行すると、50%以上のオーバーヘッド(おそらく75%)になります。 。これはInteger
、Javaで'の配列の代わりに'の配列を使用するのと同じですint
。
@Charles Dowdが言ったように、オーバーヘッドを避けるために、一度にすべてのメモリを割り当てる方がはるかに優れています。
呼び出したり、整数を読み取るたびに呼び出しmalloc
たりする必要はありません。確かにそうです。realloc
必要なスペースを見積もることができますか?ファイル形式を管理していますか?その場合、ファイルの最初の行を、ファイルから読み取る整数の数を示す単一の整数にすることができます。次に、必要なすべてのスペースを一度に割り当てることができます。フォーマットを制御できず、これを実行できない場合は、このスレッドで説明されている他の提案に従ってください。適度なサイズのバッファーを割り当て、スペースが不足するたびに2倍にします。
これはテキストファイル(バイナリではない)であり、固定形式ではありませんよね?それ以外の場合は、ファイルサイズから配列のサイズを計算するのは簡単です(buffer_size = file_size / record_size
、buffersizeはwords(intのサイズ)で、他のサイズはbytesです)。
これは私がすることです(しかし、適用される統計に関しては、私は少しおかしいです)。
1)ファイル内で数字(別名レコード)が占める最大文字数(別名バイト)はいくつですか。行末文字(CR、NF)およびその他の空白のグリフ(スペース、タブなど)?レコードの平均サイズをすでに見積もることができる場合は、最大サイズの代わりにそれを使用することをお勧めします。
initial_buffer_size = file_size / max_record_size + 1 (/ is integer division)
2)そのバッファーを割り当て、いっぱいになるまで整数をそのバッファーに読み込みます。ファイル全体が読み取られた場合は終了です。それ以外の場合は、新しい推定ニーズを満たすためにバッファのサイズを変更または再割り当てします。
resize_size =
prev_buffer_size
+ bytes_not_read / ( bytes_already_read / number_of_records_already_read )
+ 1
3)バッファがいっぱいになるまで(前回の読み取りが終了した場所から)、またはファイルのすべてが読み取られるまで、そのバッファに読み込みます。
4)終了していない場合は、新しいを使用して手順2)から繰り返しprev_buffer_size
ます。
これは、バイトサイズの観点から数値(レコード)が完全にランダムに分散されている場合に最適に機能します。そうでない場合、およびそれらがどのような分布を持っているかについての手がかりがあれば、それに応じてアルゴリズムを調整できます。