[問題] hashmap 的效能 (300mb檔案)

看板java作者 (小黑炭)時間11年前 (2012/08/26 04:08), 編輯推噓7(7010)
留言17則, 8人參與, 最新討論串1/7 (看更多)
手上有一個文字檔 300mb 檔案內容有3個 column中間隔1個空白 每一個column裡面資料長度不同 1 2 3 1.1 2 3 類似這樣 我想要把這個檔案裏面的第一欄放到HashMap裡面 這樣之後比對比較方便 (map.contain(key)) 我把第二欄與第三欄append起來做為Key值 StringBuilder sb = new StringBuilder(); String temp = ""; String key =""; while( (temp = br.readLine()) != null){ String[] items = temp.split(" "); key = sb.append(items[1]).append(items(" ")[2]).toString(); map.put(key, items[0]); sb.delete(0, sb.length()); } 這樣寫效能奇差無比... 還會爆掉 Q_Q 請問有辦法可以改善嗎 QQ? -- 不菸不酒,沒有朋友 有菸有酒,癌症好友 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 1.170.251.222

08/26 04:14, , 1F
一定要讀完整個檔嘛?
08/26 04:14, 1F

08/26 04:16, , 2F
而且用map要key保證不衝突到才行,不如說說用途? ._.
08/26 04:16, 2F
map 裡面的 key 有衝突到,會用第二次Put 進去的 value複寫吧 (Q_Q? 我不介意他複寫 所以我沒有去判斷 key 值有沒有重複 我有兩個檔案,A.txt B.txt 兩個檔案格式相近, B.txt 比 A.txt 多一欄 然後B.txt 裡面的某一欄要用 A.txt 裡面的第一欄(map 裡面的 value) 取代 我的想法是 先把 A.txt 第一欄的資料丟進去 Map 裡面,讓 B.txt 的在取代的時候 能夠快速找到value

08/26 10:08, , 3F
後兩個column字串會很大嗎? 不然不用StringBuilder
08/26 10:08, 3F

08/26 10:11, , 4F
而且 append是黏上去 sb沒重設 等於每次都把前面舊資料重複黏
08/26 10:11, 4F
我在程式裡面有加入 sb.delete(0, sb.length()); 只是寫在PTT 忘記加上去了Orz ※ 編輯: love112302 來自: 1.170.251.222 (08/26 12:08) 其實不一定要用Map QQ 我只是想問看看有沒有比較快的方法 Orz ※ 編輯: love112302 來自: 1.170.251.222 (08/26 12:11)

08/26 12:41, , 5F
用substring會比split快嗎?
08/26 12:41, 5F

08/26 12:42, , 6F
感覺split參數是regular exp 應該會慢一些...
08/26 12:42, 6F

08/26 12:45, , 7F
查了一下 http://0rz.tw/1zQXU StringTokenizer好像也不錯?
08/26 12:45, 7F
謝謝~ 我晚上會在用 StringTokenizer 試試看 感謝 ※ 編輯: love112302 來自: 1.170.251.222 (08/26 14:04) 看了一下 StringTokenizer 的用法 似乎沒辦法指定我要取出其中的那一個資料 ? 比方說像陣列一樣 [1] 這樣? 只能用順序進行嗎QQ? ※ 編輯: love112302 來自: 140.124.60.134 (08/26 20:24)

08/26 20:49, , 8F
順序...有差嗎? 你不是0,1,2都要...@@
08/26 20:49, 8F
阿 我想到了 QQ 我再試試看 ※ 編輯: love112302 來自: 140.124.60.134 (08/26 21:04) 爆掉的地方很奇怪 是在 組合成 KEY 的地方... 我key 的組合方式是 StringBuilder sb = new StringBuilder(); while( Strint temp = br.readLine() != null ){ //中略 key = sb.append(st.nextToken).append(st.nextToken); } ※ 編輯: love112302 來自: 140.124.60.134 (08/26 21:09)

08/26 21:12, , 9F
檔案格式有問題? 還是程式寫歪了 XD
08/26 21:12, 9F
我都把key印出來看 但是都是正確的 QQ.... JVM 也開到 2048 了= = ※ 編輯: love112302 來自: 140.124.60.134 (08/26 21:16)

08/26 21:15, , 10F
要看是跑到第幾行爆掉 或是第一行就爆了? 這片段資訊不足
08/26 21:15, 10F
剛剛是跑出 GC overhead limit 的錯誤 實際去看 GC 的執行時間 大概從 兩百多萬行就開始慢 資料總筆數 一千萬行 QQ ※ 編輯: love112302 來自: 140.124.60.134 (08/26 21:34)

08/26 21:43, , 11F
一千萬行..... 該改用資料庫了吧?
08/26 21:43, 11F
恩....正在從頭學資料庫 Orz ※ 編輯: love112302 來自: 140.124.60.134 (08/26 21:45)

08/27 00:41, , 12F
我懷疑 String 沒被 GC 清掉,因為 StringBuilder 是同一個
08/27 00:41, 12F

08/27 00:43, , 13F
要不要試試每次都重新 new 一個 StrinBuilder?
08/27 00:43, 13F
這個問題其實我有點困擾 因為我有滿多地方需要組合字串 我知道用 + 的方式很慢 但是如果每次都 new 一個 StringBuilder 出來用 比方說: new StringBuilder().appen(1).append(2).toString(); 然後用完就丟掉 跟宣告一個 成員變數(忘記名稱 就是宣告在 function 之外的變數) 然後所有要字串組合的地方 都用同一個 StringBuilder 用完之後 sb.delete(0, sb.length()); 哪一個比較省記憶體空間呢QQ? ※ 編輯: love112302 來自: 111.249.194.97 (08/27 01:06)

08/27 01:28, , 14F
String 應該是清不掉, 只要你的 map 還需要它的話
08/27 01:28, 14F

08/27 03:46, , 15F
這種尺度的資料 應該要寫入資料庫來處理
08/27 03:46, 15F

09/09 19:35, , 16F
因為您指出重複的key要覆蓋,那將a檔案拆成多檔去轉b檔
09/09 19:35, 16F

09/09 19:37, , 17F
a 1~100000行 + b轉出b1, a 100001~200000 + b1轉出b2...
09/09 19:37, 17F
文章代碼(AID): #1GEJ2v7C (java)
討論串 (同標題文章)
文章代碼(AID): #1GEJ2v7C (java)