Re: [問題] txt的內容(不特定長度的數字)轉成數值

看板C_and_CPP (C/C++)作者 (藍影)時間15年前 (2011/03/19 20:37), 編輯推噓2(2042)
留言44則, 4人參與, 最新討論串4/4 (看更多)
※ 引述《aiueokaki (長門教信徒)》之銘言: : 因為我的檔案沒new line : 補上檔案 : http://rapidshare.com/files/453303096/DATA.txt 測試原始碼仍以我先前發的產生器產生出來之測試為主 裡面用到一些 ascii - bitwise 技巧, 沒實測過數據取出是否正確 (不過雛形應就長那樣了) 測一次的數據結果 fscanf : 286.150 secs --> 這最慢 fgets + strtok + atoi : 193.204 secs --> 此案例不可用 fgetc + buffer + atoi : 235.073 secs ★fgetc + mult(for int) : 137.737 secs --> 這最快, 時間只有 fscanf 一半 ★fgetc + table(for int): 136.860 secs --> 這最快, 時間只有 fscanf 一半 「目前」結論 1. 資料複雜度不高,要求速度的話別用 fscanf 2. fgetc 別放在 buffer 再進行 atoi,速度拖慢 3. 最快方法為 fgetc + mult / fgetc + table, 二者速度無明顯差異, 所以應可不用建 table, 部份程式碼如下 另下載了你的原始資料 (不到 40MB, 還真有點讓我失望) 跑出來的結果 fscanf: 6.25 secs, fgetc+mult: 2.74 secs 另 loveme 提的方法是該考慮的, 如果你常使用到同一份檔案,相信先把原始資料轉出來後, 再用 fread / fseek 會更好 放上這二部份之實測連結 http://nopaste.csie.org/59cc2 while( (ch=fgetc(fp))!=EOF){ if(ch>='0' && ch<='9' ) number = 10*number + (ch & 0x0f); else number=0; } 對於實測結果有疑惑的話,歡迎一起實測,以供小弟確認 其它測試有興趣的話再提,待我測完後會再把數據放上來. (此案例用 fgetc 比 fgets 快的結果還讓人蠻訝異的..) -- YouLoveMe() ? LetItBe() : LetMeFree(); -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.72.67 ※ 編輯: tropical72 來自: 180.177.72.67 (03/19 20:55) ※ 編輯: tropical72 來自: 180.177.72.67 (03/19 21:23)

03/19 21:29, , 1F
為何不 if('0'<=ch&&ch<='9') 這樣就好了
03/19 21:29, 1F

03/19 21:32, , 2F
樓上說得是,只是考慮到filename未必為該型態,下次測試
03/19 21:32, 2F

03/19 21:32, , 3F
將改過,謝謝建議 !!
03/19 21:32, 3F

03/19 22:07, , 4F
真的很感謝!!研讀中~ 剛剛試一下,4s~5s。不知道我有沒
03/19 22:07, 4F

03/19 22:08, , 5F
有錯。跟之前自己做的時間差太多= =
03/19 22:08, 5F
電腦是在做「高負載」的動作嗎?一直以為我電腦算差,2~3 秒跑完, 沒想到你的是 4~5 秒 (即使用 fscanf 也是 6~7 秒) ※ 編輯: tropical72 來自: 180.177.72.67 (03/19 22:27)

03/19 22:25, , 6F
http://nopaste.csie.org/f4623 可以幫我測一下速度嗎?
03/19 22:25, 6F

03/19 22:44, , 7F
目前卡在 strchr,fgets read 0.593 secs (40MB file)
03/19 22:44, 7F

03/19 22:52, , 8F
atoi(p++)我忘記把指標往前了 strchr會無窮回圈
03/19 22:52, 8F

03/19 22:54, , 9F
我幫修一下
03/19 22:54, 9F
這是我以原 po 的檔案測的結果 fgetc read: 2.890 secs fgetc + num optimization(ctype): 4.969 secs (my code:2.74 secs) fgets read: 0.578 secs fgets + atoi + strchr: 3.156 secs fscanf read: 6.75 secs fscanf read num: 6.235 secs 我想請教的是, 以原 po 檔案沒有 new line, 用 fgets 方式應會切字吧? 若要用這方法, 是打算再寫一個 function 處理切字問題嗎 ? ※ 編輯: tropical72 來自: 180.177.72.67 (03/19 23:06)

03/19 23:10, , 10F
會看讀的大小fgets(s,size,fp)也就是size的部份
03/19 23:10, 10F

03/19 23:11, , 11F
恕我有點遲鈍,由於原始檔本身每位數並不固定,看 size
03/19 23:11, 11F

03/19 23:12, , 12F
似乎也沒辦法確定有沒有切到字、讀到幾個數字,是嗎?
03/19 23:12, 12F

03/19 23:17, , 13F
我想請問為啥不轉檔來做呢? 0.0/
03/19 23:17, 13F

03/19 23:21, , 14F
fscanf 6.643,fgets+strtok+atoi 3.825
03/19 23:21, 14F

03/19 23:22, , 15F
fgetc+buffer+atoi 5.116,mult 3.620,table 3.671
03/19 23:22, 15F

03/19 23:23, , 16F
這是tropical72的結果。firejox的,我晚點再測
03/19 23:23, 16F

03/19 23:30, , 17F
我之前用fgets會切字。不知道firejox寫的有沒有這個問題
03/19 23:30, 17F

03/19 23:35, , 18F
fgets最多會讀到的大小 就是size 如果要判斷切字就看最後
03/19 23:35, 18F

03/19 23:36, , 19F
和檔案指標的部份數字有沒有相連即可
03/19 23:36, 19F

03/19 23:37, , 20F
必要時用ungetc維護
03/19 23:37, 20F

03/19 23:38, , 21F
嗯,不說都忘了ungetc,的確也是要再額外處理,謝謝指教.
03/19 23:38, 21F

03/19 23:39, , 22F
@loveme00835:我於本文有提到,若檔案常讀,勢必要考慮
03/19 23:39, 22F

03/19 23:40, , 23F
您說的方式,轉成binary再用fseek/fread,此處測試應變
03/19 23:40, 23F

03/19 23:40, , 24F
成對檔案處理效能之研究 :)
03/19 23:40, 24F

03/19 23:41, , 25F
我會很暴力的全放記憶體來做 XDD
03/19 23:41, 25F

03/19 23:41, , 26F
也可以邪惡一點直接把檔案指標的內容直接比較XD
03/19 23:41, 26F

03/19 23:42, , 27F
反正也是結構體XD
03/19 23:42, 27F

03/19 23:46, , 28F
http://nopaste.csie.org/79cdd 引數檔案即可執行~~~
03/19 23:46, 28F

03/20 00:06, , 29F
fgetc read 3.53,fgetc+num optimization 6.073
03/20 00:06, 29F

03/20 00:06, , 30F
fgets read 0.617,fgetc+atoi+strchr 2.61
03/20 00:06, 30F

03/20 00:06, , 31F
fscanf read 7.421,fscanf reaf num 6.691
03/20 00:06, 31F

03/20 00:07, , 32F
真的很感謝各位的幫忙,謝謝。
03/20 00:07, 32F

03/20 00:12, , 33F
@tropical72,我最大的txt檔也只有131M,很抱歉不能進行
03/20 00:12, 33F

03/20 00:12, , 34F
更大量的測試。
03/20 00:12, 34F

03/20 00:21, , 35F
可以試著自己生檔案 開亂數去跑
03/20 00:21, 35F

03/20 00:27, , 36F
fscanf 也 parse 太久...
03/20 00:27, 36F

03/20 00:28, , 37F
我覺得..真的是先轉binary再用fseek/fread會好些,
03/20 00:28, 37F

03/20 00:28, , 38F
03/20 00:28, 38F

03/20 00:29, , 39F
接著用fseek/fread應會快很多,只要該檔用到第二次就值
03/20 00:29, 39F

03/20 00:29, , 40F
回票價了.不會批次轉的話見 z-10-1
03/20 00:29, 40F

03/20 00:33, , 41F
讀檔為何用rb?
03/20 00:33, 41F

03/20 00:36, , 42F
哈,應該我的壞習慣,以前一直只會用 "rb" 不用 "r",下次
03/20 00:36, 42F

03/20 00:36, , 43F
注意,謝謝指正 :)
03/20 00:36, 43F

03/20 00:37, , 44F
因為原po都是存成2進位檔 (誤
03/20 00:37, 44F
文章代碼(AID): #1DXAEBDq (C_and_CPP)
文章代碼(AID): #1DXAEBDq (C_and_CPP)