Re: [問題] hashmap 的效能 (300mb檔案)
原PO會記憶體不足或慢的原因,
可能是因為對Java的String處理不夠了解所致。
應該可以從以下兩點進行改善:
1.儲存成key的多個欄位,不應串接起來。
原因:A.變成更長的String耗記憶體
B.可能導致錯誤,如A,BC和AB,C都變為ABC
解法:將原本String[]包覆成List,即可在Map中計算hashCode和equals
2.如果單欄位內容重複性高,嘗試使用Java提供的String pool節省記憶體
原因:外部資料中若某欄位出現100次"2012",會佔100份char[4]和String物件的記憶體
解法:intern()會在String pool中尋找已存在的來取代,使相同字串只需消耗1份記憶體
public static Map<List<String>,List<String>> file2map(
BufferedReader br, String colSep,
int[] keyCols, int[] valCols) throws IOException {
final int keys=keyCols.length,vals=valCols.length;
final Map<List<String>,List<String>> result=new LinkedHashMap();
for( String line; null!=(line=br.readLine()); ){
final String[] cell=line.split(colSep);
final String[] key=new String[keys], val=new String[vals];
for(int i=0;i<keys;i++){
final int keyCol=keyCols[i];
key[i]=(cell[keyCol]=cell[keyCol].intern());//節省記憶體
}
for(int i=0;i<vals;i++){
final int valCol=valCols[i] ;
val[i]=cell[valCol];//假設val欄位資料重覆率低,省略intern
}
result.put(Arrays.asList(key),Arrays.asList(val));
}
return result;
}
※ 引述《love112302 (小黑炭)》之銘言:
: 手上有一個文字檔 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: 118.168.65.219
※ 編輯: ClareQ 來自: 118.168.65.219 (09/08 23:13)
討論串 (同標題文章)
完整討論串 (本文為第 7 之 7 篇):