掃瞄器的高效實現
編譯器進行詞法分析時,不可避免地需要對原始檔進行掃瞄,實現該功能的模組稱為掃瞄器。掃瞄器讀取原始檔,按序返回檔案內的字元,直到檔案結束。
掃瞄器的功能
實現檔案的讀一般使用庫函式fscanf或者fread,那麼按照怎樣的讀取方式才能讓掃瞄器的效能更佳呢?
(1)使用fscanf逐字掃瞄,並返回。
char
scan(file*file)
return ch;
} 這是最簡單的實現方式,缺點是每次讀取字元時都需要訪問檔案進行io。
我們先看看它的效率,首先在主函式內呼叫掃瞄器。
//主函式 int
main()
主函式內使用掃瞄器掃瞄測試檔案1000000次,然後使用time命令檢視**的執行時間(測試檔案可以是任意檔案,這裡不給出檔案內容了,區別只是執行的時間不同而已)。
$ time main
我們測試了五次,並取了平均值(單位:ms)。次數1
2345
平均值real
370366
374368
377371
user
112140
132144
140133.6
sys256
228240
224232
236可以計算**的cpu平均執行時間為133.6+236=369.6ms。
#define
buflen 80
intlinelen=0;
int
readpos=-1;
char
line[buflen];
char
scan(file*file)
linelen=pos;//
記錄緩衝區長度
readpos=-1;//
恢復讀取位置
} readpos++;//
移動讀取點
return line[readpos]; //
獲取新的字元
} 按照前邊的方式測試**的執行時間。次數1
2345
平均值real
374380
371371
374374
user
140124
148136
108131.2
sys232
252220
232264
240(3)和方法二類似,只是載入緩衝區時使用fread。fread的引數size表示載入資料塊的大小,count表示載入資料塊的個數,這裡每次載入buflen個1位元組資料塊。
#define
buflen 80
int
linelen=0;
int
readpos=-1;
char
line[buflen];
char
scan(file*file)
linelen=pos;//
記錄緩衝區長度
readpos=-1;//
恢復讀取位置
} readpos++;//
移動讀取點
return line[readpos]; //
獲取新的字元
} 測試**的執行時間。次數1
2345
平均值real
339332
334341
332335.6
user
9692
116108
8499.2
sys244
236216
228244
233.6
計算**的cpu平均執行時間為99.2+233.6=332.8ms,可見使用fread讀取檔案比使用fscanf的效率要高。該方法是每次載入buflen個1位元組資料塊,如果每次載入1個buflen位元組資料塊是不是更高效呢?
(4)和方法三類似,只是這裡每次載入buflen個1位元組資料塊。
#define
buflen 80
int
linelen=0;
int
readpos=-1;
char line[buflen];
static int
offset=0;//
記錄檔案指標的偏移,每次開啟檔案需要初始化為
0 char
scan(file*file)
else
linelen=pos;//
記錄緩衝區長度
readpos=-1;//
恢復讀取位置
} readpos++;//
移動讀取點
return line[readpos]; //
獲取新的字元
} 測試**的執行時間。次數1
2345
平均值real
2241
2223
2259
2223
2221
2233.4
user
620540
616600
648604.8
sys1616
1680
1640
1620
1568
1624.8
計算**的cpu平均執行時間為604.8+1624.8=2229.6ms,這有點出乎意料。分析原因,可能是因為檔案較小時,當讀取到最後一塊緩衝區時,撤回檔案指標比較消耗時間。因此,使用方法三實現的掃瞄器效能更穩定,且**更簡潔。
(5)如果使用fread不是讀入1個buflen位元組資料,而是讀取buflen/2個2位元組資料,那麼最後一次將讀入最後乙個位元組。
#define
buflen 80
int
linelen=0;
int
readpos=-1;
char
line[buflen];
char
scan(file*file)
else
linelen=pos;//
記錄緩衝區長度
readpos=-1;//
恢復讀取位置
} readpos++;//
移動讀取點
return line[readpos]; //
獲取新的字元
} 測試**的執行時間。次數1
2345
平均值real
663657
646665
659658
user
208224
204212
184206.4
sys452
428440
456472
449.6
計算**的cpu平均執行時間為206.4+449.6=656ms。雖然該方法不需要撤回檔案指標,但是效能仍不如方法三。
綜上所述,方法三是實現掃瞄器比較高效的方式:使用緩衝區代替檔案的頻繁訪問,並在緩衝區讀取完畢時,使用fread每次載入buflen個1位元組資料塊更新緩衝區資料。希望本文對你有所幫助。
掃瞄器的高效實現
編譯器進行詞法分析時,不可避免地需要對原始檔進行掃瞄,實現該功能的模組稱為掃瞄器。掃瞄器讀取原始檔,按序返回檔案內的字元,直到檔案結束。掃瞄器的功能 實現檔案的讀一般使用庫函式fscanf或者fread,那麼按照怎樣的讀取方式才能讓掃瞄器的效能更佳呢?1 使用fscanf逐字掃瞄,並返回。char ...
python實現高效的埠掃瞄器基礎
一 點睛 如今網際網路安全形勢日趨嚴峻,給系統管理員帶來很大的挑戰,網路的開放性以及黑客的攻擊是造成網路不安全的主因。稍有疏忽將給黑客帶來可乘之機,給企業帶來無法彌補的損失。比如由於系統管理員誤操作,導致核心業務伺服器的22 21 3389 3306等高危埠暴露在網際網路上,大大提高了被入侵的風險。...
掃瞄器詳解
一 掃瞄器的定義 掃瞄器是一種獲取影象的裝置,並將資訊轉為電腦可以顯示 編輯 儲存和輸出的數字格式。即可以完成以下工作 在檔案中插隊圖和 將文字識別,免去打字 將傳真檔案掃到庫中存檔 在多 中加入影象 在報刊中加入有效表達主題。二 掃瞄器的工作原理 將光線照到待掃瞄的稿件上,光線反向回平後再由乙個稱...