簡體   English   中英

Java - 如何有效地存儲大量的String數組

[英]Java - how to efficiently store a large amount of String arrays

我正在嘗試使用Java高效加載大型CSV格式的文件(通常為200-600mb)(內存更少,訪問速度更快)。 目前,該程序正在使用字符串數組列表。 之前使用Lua程序處理此操作,該程序使用每個CSV行的表和用於保存每個“行”表的表。

以下是內存差異和加載時間的示例:

  • CSV文件 - 232mb
  • Lua - 內存中549mb - 加載157秒
  • Java - 內存中1,378mb - 加載12秒

如果我沒記錯的話,Lua表中的重復項存在作為對實際值的引用。 我懷疑在Java示例中,List正在保存每個重復值的單獨副本,這可能與更大的內存使用量有關。

以下是CSV文件中數據的一些背景知識:

  • 每個字段由一個字符串組成
  • 每行內的特定字段可以包括一組字符串中的一個(例如,字段3可以是“紅色”,“綠色”或“藍色”)。
  • 內容中有許多重復的字符串。

以下是加載數據可能需要的一些示例:

  • 搜索所有嘗試與給定String匹配的字符串並返回匹配的字符串
  • 在GUI表中顯示匹配項(可通過字段排序)。
  • 更改或替換字符串。

我的問題 - 是否有一個集合需要更少的內存來保存數據但仍然提供了輕松快速地搜索/排序數據的功能?

一個簡單的解決方 如果您將引用所有唯一字符串,則可以使用一些HashMap ArrayList您將只引用HashMap現有的唯一字符串。

就像是 :

private HashMap<String, String> hashMap = new HashMap<String, String>();

public String getUniqueString(String ns) {
   String oldValue = hashMap.get(ns);
   if (oldValue != null) { //I suppose there will be no null strings inside csv
    return oldValue;
   }        
   hashMap.put(ns, ns);
   return ns;
}

用法簡單:

List<String> s = Arrays.asList("Pera", "Zdera", "Pera", "Kobac", "Pera", "Zdera", "rus");
List<String> finS = new ArrayList<String>();
for (String er : s) {
   String ns = a.getUniqueString(er);
   finS.add(ns);
}

為了優化您的內存問題,我建議使用Flyweight模式,特別是對於具有大量重復項的字段。

作為集合,您可以使用TreeSetTreeMap

如果你給你的LineItem類提供了一個很好的實現(實現equalshashcodeComparable ),你可以大量優化內存使用。

DAWG

有向無環字圖是存儲字的最有效方式(無論如何最適合存儲器消耗)。

但是這里可能有點過分,正如其他人所說的那樣,不創建重復項只是對同一個實例進行多次引用。

也許這篇文章可以提供一些幫助:

http://www.javamex.com/tutorials/memory/string_saving_memory.shtml

就像旁注一樣。

對於你懷疑的重復字符串數據,你不必擔心這一點,因為java本身都在關心它,因為所有字符串都是final,並且所有引用都以內存中的同一對象為目標。

所以不確定lua是如何完成工作的,但在java中它應該也非常有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM