ios::sync_with_stdio(false)詳細
コンテストでは、大きなデータに遭遇すると、ファイルの読み取りがプログラムの実行速度のボトルネックになり、より速い読み取り方法が必要になることが多い.ほとんどのC++学習者がcinマシンの遅い速度に失敗したと信じ、cinでデータを読まないことを誓った.Pascalのread文の速度はC/C++ではscanfに及ばず、C++選手は焦るしかないという人もいる.まさかC++は本当に低Pascal一等ですか?答えは言うまでもない.1つのステップアップの方法は、データを一気に読み込んで文字列を変換することです.この方法は伝説的にはいいですが、具体的には試したことがありません.そのため、今日は思いつくすべてのデータを読む方法をいっそテストしました.結果は驚くべきものでした.
コンテストでデータを読む場合が一番多いのは整数をたくさん読むことです.そこで私はプログラムを書いて、1千万個のランダム数をdataに生成しました.txtでは、全部で55 MBです.次に、プログラムの主幹計算の実行時間を書きました.コードは次のとおりです.
最も簡単な方法はサイクルscanfを書いても、コードは以下の通りです.
最も簡単な方法はサイクルscanfを書いても、コードは以下の通りです.
しかし、効率はどうですか.私のパソコンLinuxプラットフォームでのテスト結果は2.01秒です.次はcinです.コードは次のとおりです.
予想外にcinは6.38秒しかかからず、思ったより速かった.cinが遅いのは理由がありますが、デフォルトではcinとstdinは常に同期しています.つまり、ファイルポインタの混乱を心配する必要はありません.coutとstdoutも同じで、両者の混用は出力順序が乱れません.この互換性の特性だけにcinに余分なオーバーヘッドがたくさんあるので、どのようにこの特性を無効にしますか?文std::ios::sync_with_stdio(false);,これによりcinのstdinへの同期をキャンセルできます.手順は次のとおりです.
同期をキャンセルした後の効率はどうなりますか?テスト実行時間は2.05秒に激減し、scanf効率とほぼ同じです!これがあればcinとcoutを安心して使えます.次に、ファイル全体を読み込んで処理する方法をテストします.まず、文字列を配列に変換する関数を書きます.コードは次の通りです.
ファイル全体を文字列に読み込む最も一般的な方法はfreadで、コードは以下の通りです.
上記のコードは驚くべき効率を持っており、テストで読み取った1000000個の数は0.29秒で、効率はほぼ10倍に向上した.方法を身につけていると無敵ですが、freadはパッケージされたreadだと覚えていますが、readをそのまま使うと、もっと速いのではないでしょうか.コードは次のとおりです.
END!!!!!!!!!!!!!!!!!!!!
コンテストでデータを読む場合が一番多いのは整数をたくさん読むことです.そこで私はプログラムを書いて、1千万個のランダム数をdataに生成しました.txtでは、全部で55 MBです.次に、プログラムの主幹計算の実行時間を書きました.コードは次のとおりです.
最も簡単な方法はサイクルscanfを書いても、コードは以下の通りです.
#include
int main()
{
int start = clock();
//DO SOMETHING
printf("%.3lf
",double(clock()-start)/CLOCKS_PER_SEC);
}
最も簡単な方法はサイクルscanfを書いても、コードは以下の通りです.
int numbers[MAXN];
void scanf_read()
{
freopen("data.txt","r",stdin);
for (int i=0;i
しかし、効率はどうですか.私のパソコンLinuxプラットフォームでのテスト結果は2.01秒です.次はcinです.コードは次のとおりです.
const int MAXN = 10000000;
int numbers[MAXN];
void cin_read()
{
freopen("data.txt","r",stdin);
for (int i=0;i> numbers[i];
}
予想外にcinは6.38秒しかかからず、思ったより速かった.cinが遅いのは理由がありますが、デフォルトではcinとstdinは常に同期しています.つまり、ファイルポインタの混乱を心配する必要はありません.coutとstdoutも同じで、両者の混用は出力順序が乱れません.この互換性の特性だけにcinに余分なオーバーヘッドがたくさんあるので、どのようにこの特性を無効にしますか?文std::ios::sync_with_stdio(false);,これによりcinのstdinへの同期をキャンセルできます.手順は次のとおりです.
const int MAXN = 10000000;
int numbers[MAXN];
void cin_read_nosync()
{
freopen("data.txt","r",stdin);
std::ios::sync_with_stdio(false);
for (int i=0;i> numbers[i];
}
同期をキャンセルした後の効率はどうなりますか?テスト実行時間は2.05秒に激減し、scanf効率とほぼ同じです!これがあればcinとcoutを安心して使えます.次に、ファイル全体を読み込んで処理する方法をテストします.まず、文字列を配列に変換する関数を書きます.コードは次の通りです.
const int MAXS = 60*1024*1024;
char buf[MAXS];
void analyse(char *buf,int len = MAXS)
{
int i;
numbers[i=0]=0;
for (char *p=buf;*p && p-buf
ファイル全体を文字列に読み込む最も一般的な方法はfreadで、コードは以下の通りです.
const int MAXN = 10000000;
const int MAXS = 60*1024*1024;
int numbers[MAXN];
char buf[MAXS];
void fread_analyse()
{
freopen("data.txt","rb",stdin);
int len = fread(buf,1,MAXS,stdin);
buf[len] = '\0';
analyse(buf,len);
}
上記のコードは驚くべき効率を持っており、テストで読み取った1000000個の数は0.29秒で、効率はほぼ10倍に向上した.方法を身につけていると無敵ですが、freadはパッケージされたreadだと覚えていますが、readをそのまま使うと、もっと速いのではないでしょうか.コードは次のとおりです.
const int MAXN = 10000000;
const int MAXS = 60*1024*1024;
int numbers[MAXN];
char buf[MAXS];
void read_analyse()
{
int fd = open("data.txt",O_RDONLY);
int len = read(fd,buf,MAXS);
buf[len] = '\0';
analyse(buf,len);
}
END!!!!!!!!!!!!!!!!!!!!