1. 程式人生 > >四種讀入方式的效率對比

四種讀入方式的效率對比

序:
之前在一篇關於vector的push_back和resize()等方式讀取資料的效率對比中,我們發現最快的是通過讀入優化。這次將測試四種讀入方式的效率對比:
兩種讀入優化,scanf與fscanf。
測試資料採用隨機生成的10000000個int型整數,在windows環境下執行。
測試時間由time.h中的函式計算。

四種讀取方式:

int input;
inline void read1(int &curr)
{
    static char c;
    c = getchar();
    while(c < '0' || c > '9')   c = getchar();
    while
(c >= '0' && c <= '9') { curr = curr*10+c-'0'; c = getchar(); } return ; } inline void read2() { static char c; //int input = 0; input = 0; c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9'
) { input = input*10+c-'0'; c = getchar(); } //return input; return ; } void Init1()//傳地址 { freopen("test.in", "r", stdin); int n = 0, i; int startTime = clock(); read1(n); for(unsigned i = 0; i != n; ++i) { read1(m[i]); } int endTime = clock(); ans[1
] += (double)(endTime-startTime)/CLOCKS_PER_SEC; //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << endl; fclose(stdin); } void Init2()//利用全域性變數 { freopen("test.in", "r", stdin); //freopen("test.out", "w", stdout); int n = 0, i, j; int startTime = clock(); read2(); n = input; for(unsigned i = 0; i != n; ++i) { read2(); m[i] = input; } int endTime = clock(); ans[2] += (double)(endTime-startTime)/CLOCKS_PER_SEC; //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << endl; fclose(stdin); //fclose(stdout); } void Init3()//檔案讀入 { int i, n; FILE *fp = fopen("test.in", "rb"); int startTime = clock(); fscanf(fp, "%d", &n); for(unsigned i = 0; i != n; ++i) { fscanf(fp, "%d", &m[i]); } int endTime = clock(); ans[3] += (double)(endTime-startTime)/CLOCKS_PER_SEC; //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << "s" <<endl; fclose(fp); } void Init4()//普通 { int i, n; freopen("test.in", "r", stdin); int startTime = clock(); scanf("%d", &n); for(unsigned i = 0; i != n; ++i) { scanf("%d", &m[i]); } int endTime = clock(); ans[4] += (double)(endTime-startTime)/CLOCKS_PER_SEC; //cout << "Totle Time : " << (double)(endTime-startTime)/CLOCKS_PER_SEC << "s" <<endl; fclose(stdin); }

很顯然後兩種相對較慢,所以分兩組進行測試:(1,2)和(3,4)。

對於兩種讀入優化,我們的測試方法是迴圈50次算總時間與平均時間。
結果如下:
這裡寫圖片描述
看來相比於傳地址,設定一個全域性變數還是更快一些。平均快18ms。

對於3,4的讀入,我們迴圈10次。
結果如下:
38.773s
37.575s
看得出相比於檔案讀入,scanf還是更勝一籌。

那麼小資料哪?

測試5000個int型整數的讀入時間(迴圈10次)。
結果如下:
這裡寫圖片描述

結果依然。

100個(10次)。
這裡寫圖片描述
突然fscanf變得很快。

總而言之,小資料讀入優化並沒有什麼用,當總資料超過百萬的時候會體現出較大差距
(100000*10的時候:
0.059000 0.005900
0.057000 0.005700
0.393000 0.039300
0.372000 0.037200)讀入時間相差300+ms
十萬時是30+ms。若達到千萬那麼前兩種只是後兩種的零頭,差距巨大(3.3s)。
以此可見,讀入越大的資料的時候讀入優化越重要,一個讀入優化可能就能將TLE的程式AC(前提是你演算法是對的…)。

箜瑟_qi 2017.04.15 14:19