掃瞄器的高效實現

2022-01-30 07:39:59 字數 3636 閱讀 6653

掃瞄器的高效實現

編譯器進行詞法分析時,不可避免地需要對原始檔進行掃瞄,實現該功能的模組稱為掃瞄器。掃瞄器讀取原始檔,按序返回檔案內的字元,直到檔案結束。

掃瞄器的功能

實現檔案的讀一般使用庫函式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等高危埠暴露在網際網路上,大大提高了被入侵的風險。...

掃瞄器詳解

一 掃瞄器的定義 掃瞄器是一種獲取影象的裝置,並將資訊轉為電腦可以顯示 編輯 儲存和輸出的數字格式。即可以完成以下工作 在檔案中插隊圖和 將文字識別,免去打字 將傳真檔案掃到庫中存檔 在多 中加入影象 在報刊中加入有效表達主題。二 掃瞄器的工作原理 將光線照到待掃瞄的稿件上,光線反向回平後再由乙個稱...