在資訊學競賽中,輸入資料規模可能會很大,這時候就需要注意檔案讀取的效率,本文在 Linux 環境下測驗了 C++ 幾種常見讀入方式的效率,
1. 系統環境
Arch Linux x86_64
默認 Linux 內核,版本 6.1.3
gcc 12.2.0
ext4
2. 測驗代碼
編譯命令(省略檔案):g++ -std=c++20,不開優化,
2.0 隨機整數(32位有符號)生成
#include <climits>
#include <fstream>
#include <random>
using namespace std;
using i64 = long long;
int main()
{
constexpr int N = 10000;
ofstream fout("in");
random_device rd;
mt19937 gen(rd());
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j)
fout << (i64)gen() + (i64)INT_MIN << ' ';
fout << '\n';
}
return 0;
}
2.1 freopen + scanf
#include <cstdio>
using namespace std;
int main()
{
freopen("in", "r", stdin);
constexpr int N = 10000;
int x;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
scanf("%d", &x);
return 0;
}
2.2 FILE*
#include <cstdio>
using namespace std;
int main()
{
FILE *fp = fopen("in", "r");
constexpr int N = 10000;
int x;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
fscanf(fp, "%d", &x);
return 0;
}
2.3 ifstream
#include <fstream>
using namespace std;
int main()
{
ifstream fin("in");
constexpr int N = 10000;
int x;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
fin >> x;
return 0;
}
2.4 freopen + cin
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("in", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(nullptr);
constexpr int N = 10000;
int x;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
cin >> x;
return 0;
}
2.5 快讀
從洛谷模板題快速排序的最優解復制的快讀模板(做了少量修改)
#include <cctype>
#include <cstdio>
#include <cstring>
using namespace std;
namespace IO
{
class qistream
{
static const size_t SIZE = 1 << 16, BLOCK = 32;
FILE *fp;
char buf[SIZE];
int p;
public:
qistream(FILE *_fp = stdin) : fp(_fp), p(0)
{
fread(buf + p, 1, SIZE - p, fp);
}
void flush()
{
memmove(buf, buf + p, SIZE - p), fread(buf + SIZE - p, 1, p, fp), p = 0;
}
qistream &operator>>(char &str)
{
str = getch();
while (isspace(str))
str = getch();
return *this;
}
template <class T> qistream &operator>>(T &x)
{
x = 0;
p + BLOCK >= SIZE ? flush() : void();
bool flag = false;
for (; !isdigit(buf[p]); ++p)
flag = buf[p] == '-';
for (; isdigit(buf[p]); ++p)
x = x * 10 + buf[p] - '0';
x = flag ? -x : x;
return *this;
}
char getch() { return buf[p++]; }
qistream &operator>>(char *str)
{
char ch = getch();
while (ch <= ' ')
ch = getch();
for (int i = 0; ch > ' '; ++i, ch = getch())
str[i] = ch;
return *this;
}
};
} // namespace IO
int main()
{
FILE *fp = fopen("in", "r");
IO::qistream fin(fp);
constexpr int N = 10000;
int x;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
fin >> x;
return 0;
}
3. 測驗方法
- 運行一遍隨機整數生成,輸出的
in檔案作為 5 份代碼共同的輸入檔案, - 依次運行 5 份代碼,每份代碼運行 5 次,使用 bash 內置
time命令進行計時,取最后 3 次運行時間取平均數,
4. 測驗結果
| freopen + scanf | FILE* | ifstream | freopen + cin | 快讀 |
|---|---|---|---|---|
| 10.471s | 10.485s | 6.767s | 6.889s | 4.967s |

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/541332.html
標籤:其他
上一篇:Python 函式遞回教程
下一篇:學習筆記——過濾器的匹配規則
