作者tropical72 (藍影)
看板C_and_CPP
標題Re: [問題] txt的內容(不特定長度的數字)轉成數值
時間Sat Mar 19 03:09:05 2011
原文恕刪, po 上我認為重要的資訊
: a. 檔案長相
: 598 65 127 3456 234 674
: 76 356 3245 765 23 5632
: b. 512x614x224。
: c. 要從裡面切200x200x224出來。跑超久的Orz
: d. 資料是m x n x k的矩陣形式
1. 首先我從 (a) 判斷應是有 new line,
何不先使用 fgets 把前面沒用到的都濾掉?
這部份應是簡單的數學計算便可算出該濾掉幾行
也只有看過原始資料的你最清楚該怎麼算
2. 建議先實測一個東西..
(2.1) 全都用 fscanf 去讀一個文字檔所有欄位
(2.2) 使用 fgets + strtok + atoi(atof) 去讀文字檔所有欄位
我不知道是哪個快,但 "直覺" 是 (2.2),
因 "直覺" 告訴我檔案 IO 速度應沒在 mem 上操作快,
所以才會想用 fgets + strtok + atoi(atof) 去減少 IO 次數
上述的確沒什麼神奇的方法, 若有想到的話再補上來好了.
※ 大檔案的處理如果不是用 binary 存, 是真的會跑很久..
----- 測試分隔線 ----- 測試分隔線 ----- 測試分隔線 -----
1. 以亂數產生 512*614*224 亂數寫入 data.txt 中
http://nopaste.csie.org/19ab1
這裡生成出來的 data.txt 將近 2G, 我想你的原始資料應也是如此。
2. os: xp ,
CPU: 2.91G 雙核 (AMD Athlom(tm) II X2 245)
RAM: 2.75G
分別以 fgets, fgets + strtok + atoi, fscanf 測試讀取時間
http://nopaste.csie.org/6537c
fgets : 33.984 secs (UINT: 1) / 第一維平均耗時 34/512 = 0.066
fgets+strtok+atoi : 192.734 secs (UINT: 5.67) / 第一維平均耗時 193/512 = 0.377
fscanf : 301.735 secs (UINT: 8.878)/ 第一維平均耗時 302/512 = 0.590
實測結果,用 fgets + strtok + atoi 取代 fscanf 可節省約 1/3 (36%) 時間
若是從 512*614*224 取 220*220*224,使用上述之方法,
fgets 濾除 + [fgets + strtok + atoi 取值]
預計時間約 100 secs,(為粗略計算,下列算式)
"至少" 又可再節省 1/3 (34%) 時間,共省下 66% 時間,
故可考慮上述方式取代 fscanf 。
若取出之數字為浮點數 [fgets + strtok + atof],想必應得重新測時。
※ 算式: 0.066 * (512-220) + 0.377 * (220) = 102.212 secs
PS: 我只是想說,檔案 IO 的速度不論是讀檔還是寫檔真的都該研究一下。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.72.67
※ 編輯: tropical72 來自: 180.177.72.67 (03/19 04:37)
推 danielguo:讀進來再 parse 可以只對需要的數字做 atoi 的確較快 03/19 05:14
推 ericinttu:有數據有推 03/19 06:39
推 aiueokaki:真的太感謝了!!!想不到還用數據實際測試!學習了~謝謝!! 03/19 10:42
→ firejox:用fgetc來判斷吃了幾個'\n'就可以了 03/19 15:05
→ firejox:因為用fgets還要有暫存空間 03/19 15:05
→ tropical72:用fgetc?fscanf已比較慢了,fgetc會較快嗎? 03/19 16:02
→ loveme00835:通常有buffering, 就差在函式呼叫 03/19 16:04
→ firejox:@tropical: fgets就是一連串的fgetc阿 03/19 16:11
→ tropical72:@firejox: fgets 為一連串之 fgetc 是真的不知道,我找 03/19 16:18
→ tropical72:一下有沒有相關說明,謝謝您的指教. 03/19 16:18
→ loveme00835:標準裡並沒規定fgets要用fgetc來實作阿, 它也可以直接 03/19 16:20
→ loveme00835:從緩衝拿東西 03/19 16:20
→ tropical72:嗯,目前我單純用 fgetc 跑的確跑了 5mins 還沒跑完 XD 03/19 16:25