さらに、文字列を読んだ後でその文字列にほとんど何もしない(たとえば、「grep」のようなものを書いているので、ほとんどの場合、単に文字列を見つけるために読んでいる)。あなたが過ごす時間の大部分です。
しかし、「ファイル全体を一度にロードする」には、いくつかの明確な問題があります。
>ファイル全体を読むまで処理を始めません。
>ファイル全体をメモリに読み込むのに十分なメモリが必要です – ファイルのサイズが数百GBの場合はどうなりますか?あなたのプログラムはそれから失敗しますか?
プロファイリングを使用して、コードの実行速度が遅くなる原因の一部であることを証明していない限り、何かを最適化しないでください。あなたは自分自身のためにより多くの問題を引き起こしているだけです。
編集:だから、私はそれが非常に面白いと思うので、私はこれを測定するためのプログラムを書きました。
比較結果を公平にするために、1つの1297984192バイトの大きなファイルを3つ作成しました(ディレクトリ内のすべてのソースファイルを約12種類の異なるソースファイルでコピーし、次にこのファイルを何度かコピーして「乗算」します)。テストを実行するのに1.5秒以上かかるまで、それはタイミングがランダムな「ネットワークパケットが入ってきた」またはタイムアウトをとる他の何らかの外部の影響をあまり受けないようにするために物事を実行する必要があると思いますプロセスの)。
私はまたプロセスによってシステムとユーザー時間を測定することにしました。
$ ./bigfile
Lines=24812608
Wallclock time for mmap is 1.98 (user:1.83 system: 0.14)
Lines=24812608
Wallclock time for getline is 2.07 (user:1.68 system: 0.389)
Lines=24812608
Wallclock time for readwhole is 2.52 (user:1.79 system: 0.723)
$ ./bigfile
Lines=24812608
Wallclock time for mmap is 1.96 (user:1.83 system: 0.12)
Lines=24812608
Wallclock time for getline is 2.07 (user:1.67 system: 0.392)
Lines=24812608
Wallclock time for readwhole is 2.48 (user:1.76 system: 0.707)
ここにファイルを読むための3つの異なる関数があります(もちろん時間とものを測定するためのいくつかのコードがあります、しかしこの記事のサイズを減らすために、私はそれを全部投稿しないことにします – 違いがあるので、上記の結果はここの関数と同じ順序ではありません。
void func_readwhole(const char *name)
{
string fullname = string("bigfile_") + name;
ifstream f(fullname.c_str());
if (!f)
{
cerr << "could not open file for " << fullname << endl;
exit(1);
}
f.seekg(0, ios::end);
streampos size = f.tellg();
f.seekg(0, ios::beg);
char* buffer = new char[size];
f.read(buffer, size);
if (f.gcount() != size)
{
cerr << "Read failed ...\n";
exit(1);
}
stringstream ss;
ss.rdbuf()->pubsetbuf(buffer, size);
int lines = 0;
string str;
while(getline(ss, str))
{
lines++;
}
f.close();
cout << "Lines=" << lines << endl;
delete [] buffer;
}
void func_getline(const char *name)
{
string fullname = string("bigfile_") + name;
ifstream f(fullname.c_str());
if (!f)
{
cerr << "could not open file for " << fullname << endl;
exit(1);
}
string str;
int lines = 0;
while(getline(f, str))
{
lines++;
}
cout << "Lines=" << lines << endl;
f.close();
}
void func_mmap(const char *name)
{
char *buffer;
string fullname = string("bigfile_") + name;
int f = open(fullname.c_str(), O_RDONLY);
off_t size = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);
buffer = (char *)mmap(NULL, size, PROT_READ, MAP_PRIVATE, f, 0);
stringstream ss;
ss.rdbuf()->pubsetbuf(buffer, size);
int lines = 0;
string str;
while(getline(ss, str))
{
lines++;
}
munmap(buffer, size);
cout << "Lines=" << lines << endl;
}
関連記事
- bash - ファイルからの読み込み中にシェルスクリプトで文字列を分割する
- file-io - ファイルからの読み込み中にclojureで行を分割する
- java - ファイルを読み込み、複数の基準に基づいて各行を切り取ります
- Pythonでファイル(または標準入力)を1行ずつ読み込む方法で、ファイル全体の読み込みを待たない
- typescript - スペースに基づいて文字列を分割し、それをangular2で読み込む
- hadoop - Apache Sparkは同時に読み込みと処理を行いますか、それとも最初にメモリ内のファイル全体を読み込み、次に変換を開始しますか?
- javascript - 画像の読み込み中に読み込み中アイコンを表示する
- html - iframeページコンテンツの読み込み中に読み込み中のGIFを表示する
転載記事の出典を記入してください: c – ファイルの読み込み中、ファイル全体の読み込み中にgetlineを実行し、その後改行文字に基づいて分割する - コードログ