1

メモリに大きな配列があります。私はこれをファイルに書いています:

             FILE* fp = fopen("filename", "wb");
             fwrite(array, sizeof(uint32_t), 1500000000 , fp); // array saved
             fflush(fp) ;
             fclose(fp);

次を使用して再度読み取ります。

              FILE* fp = fopen("filename", "rb");
              fread(array, sizeof(uint32_t), 1500000000 , fp);
              fclose(fp);

書き込みには 7 秒、読み取りには 5 秒かかります。

実際には、配列全体を記述する必要はありません。条件を確認しながら書いたり読んだりしなければなりません。のように (例):

#include<iostream>
#include <stdint.h>
#include <cstdio>
#include <cstdlib>
#include <sstream>

using namespace std;

main()
{
      uint32_t* ele = new uint32_t [100] ;
      for(int i = 0; i < 100 ; i++ )
      ele[i] = i ;

      for(int i = 0; i < 100 ; i++ ){
          if(ele[i] < 20)
          continue ;
          else
          // write  ele[i] to file
          ;   
      }

 for(int i = 0; i < 100 ; i++ ){
          if(ele[i] < 20)
          continue ;
          else
          // read  number from file
          // ele[i] = number * 10 ;
          ;   
      }

     std::cin.get();
}

このため、私がやっていることは次のとおりです。

使用して書く:

for(int i = 0; i < 1500000000 ; i++ ){
if (arrays[i] < 10000000)
continue ;
uint32_t number = arrays[i] ;
fwrite(&number, sizeof(uint32_t), 1, fp1);
}

そして、次を使用して読む:fread(&number, sizeof(uint32_t), 1, fp1);

この場合、書き込みには 2.13 分、読み取りには 1.05 分かかります。

これは私にとってかなり長い時間です。なぜこれが起こっているのですか(2番目のケースではファイルサイズが最初のものよりも小さい)? そして、この問題を解決する方法は? 他のより良いアプローチはありますか?

4

4 に答える 4

2

少し前にこれをベンチマークしましたが、私のボックスでは、多くの小さなfwrite()呼び出しは約90 MB / sしか維持できません(ディスクはこれよりもはるかに高速であるため、テストはディスクにバインドされていませんでした)。

私の提案は、独自のバッファリングを行うことです。値を中間配列に書き込み、時々、単一のを使用して配列全体を書き出しfwrite()ます。

于 2013-01-24T10:30:50.320 に答える
1

一度だけ書くとずっと速くなります。印刷する要素だけを使用して補助配列を作成し、この配列を1回のfwrite呼び出しで書き込むことをお勧めします。もちろん、これには追加のメモリが必要になりますが、これは標準的なトレードオフであり、パフォーマンスのためのメモリです。

于 2013-01-24T10:22:23.923 に答える
1

C の FILE* ルーチンはバッファリングされますが、各呼び出しにはまだかなりの量のオーバーヘッドがあります。最終的に数百万回の整数サイズの読み取り/書き込みを行うと、パフォーマンスが低下します。

編集:速度の最適化の試みとして、整数サイズの読み取りを行っていますか? それとも、何らかのデータの一貫性を保つために行っているのでしょうか (つまり、配列内の整数は、条件が true の場合にのみ更新する必要があります)。

一貫性の理由から、一度にチャンク (おそらく 4k 以上) を読み取ることを検討してから、データのチャンクから比較と更新を行うか、ターゲット プラットフォームで利用可能な場合は、メモリ マップされたファイルを使用します( s)。

于 2013-01-24T10:28:05.417 に答える
0

質問のタイトルには C++ と書かれているので、優れたバッファ付きストリーム機能を使用してみませんか? C++ ofstream ファイルの書き込みはバッファを使用しますか?

于 2013-01-24T10:49:42.883 に答える