3

餿主意:DIR 結果轉存檔案,若同步輸出到螢幕會變多慢?

 2 years ago
source link: https://blog.darkthread.net/blog/dir-redirect-stdout-is-slow/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

餿主意:DIR 結果轉存檔案,若同步輸出到螢幕會變多慢?-黑暗執行緒

有些你以為不會錯的直覺,實際上錯得離譜。

清理 750 萬個檔案資料夾文章提到,我選擇將 DIR 結果寫成檔案方便反覆測試調整,轉存過程用了一招將 DIR 結果同時輸出到檔案與螢幕,理由是看得到進度能化解等待焦慮,有益急躁老人心血管保健。但不少讀者提醒此舉讓原本很耗時的 DIR 轉存動作雪上加霜,乃不智之舉;而依我的直覺,重導到螢幕輸出屬記憶體與 UI 顯示作業,增加的資料處理與顯示運算與 DIR 運算量相比不算嚴重(事實證明這個直覺大錯特錯),不致嚴重拖累效能,反正不想觀察時將 CMD 視窗最小化便可省去晝面 Render 運算,久久再顯示窺探一下,藉此換取資訊掌握度應屬划算。

不過,後來研究 NTFS 檔案佔用磁碟大小 (Size On Disk),呼應了讀者朋友們的分析,DIR 是由 MFT 讀取檔案資訊,每筆記錄 1KB,750 萬個檔案 7.5GB,就算記錄分散各處,用機械硬碟用隨機讀取 4K QD32 標準 33MB/s 評估,DIR 怎麼也不該慢到數小時,莫非這一切是輸出導向到螢幕造成的?

Fig1_637953667357033480.png

要得到答案,做實驗吧。

【實驗方式】

用 RDP 連上 Windows 10 PC,借用上回建立的兩百萬個檔案當實驗材料,以 Cmder 執行 dir X:\2MFiles > dir.txt(結果直接轉存檔案) 及 dir X:\2MFiles | tee dir.txt(結果同時輸出到檔案及螢幕),後者測兩次,一次全程開啟 Cmder 觀察顯示文件、一次將 Cmder 最小化。每次測試前先重新開機,並等待五分鐘再跑測試,排除 Cache 效應及系統服務啟動初期的磁碟 IO。

測試程式如下:

del dir.txt
dir X:\2MFiles > dir.txt
powershell .\check.ps1

check.ps1 會檢查 dir.txt 的建立時間及最後寫入時間,計算 dir 耗用時間長短:

$st = (Get-Item dir.txt).CreationTime
$ed = (Get-Item dir.txt).LastWriteTime
"dir.txt size = $((Get-Item dir.txt).Length.ToString('n0'))"
"Start: $($st.ToString('HH:mm:ss.fff')) End: $($ed.ToString('HH:mm:ss.fff'))"
([TimeSpan]($ed - $st)).TotalMilliseconds.ToString('n3')

第一次測試 dir 結果純寫檔不輸出到螢幕,91.5s 完成。(以 200 萬乘每筆檔案記錄 1KB 推算,資料量 1GB,dir.txt 166KB 寫入部分不計,2G / 91s 約 22MB/s,蠻合理的)

Fig2_637953667357451516.png

用 tee 轉接到螢幕輸出,時間暴增 30 倍,花了 2700 秒:(註:我忘了 chcp 65001 切 UTF-8 字元變花,懶得重跑請大家無視)

Fig4_637953667358311848.png

那... 把命令列視窗關起來總會好一些吧?有! 快了三倍,但還是比不顯示慢了 10 倍:

Fig5_637953667358762774.png

心得:不要盲目相信自己的直覺,多聽不一樣的聲音,有任何疑義,回歸科學邏輯檢驗就對了,以免背離真理而不自知。(感謝 Vt, dir, Daniel Hou 的留言回饋)

以上的實驗結果,不代表 tee 這招不能用,要視應用情境。本案例是因為 200 萬筆檔案目錄資料的磁碟讀取時間遠底於列印 200 萬行文字所需時間,才會造成導向螢幕慢了 30 倍。換個上傳 1000 筆資料的情境,若上傳一筆耗時 5 秒,要顯示的資料量只有 1000 筆,那麼用 tee 存檔兼顯示不會有任何效能衝擊,可以安心使用。

回到最初的問題上,如果用 dir 接 tee 太慢,但看不到進度又會焦慮怎麼辦?其實有個好辦法,dir X:\2MFiles > dir.txt 直接導向,再用 tail 偷看最後幾行就好了,我阿呆~

Fig6_637953667359230883.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK