2012-08-09 65 views
1

我創建了一個自定義表,不是從JTable擴展的,而且我有大量的數據大約4.000.000字符串數據(10%uniq字符串)。現在我創建並編制索引,如下所示:Java表索引存儲在堆中?

我爲每一列創建索引。當用戶使用我的表的實時搜索功能時,我使用treeset來合併數據。

指數:

的ArrayList其表示列:
第1列|第2列|第3列|柱4
每個元素的數組列表包含表示索引HasMap:
鍵 - >的數據字符串
值 - >的值表示哪些行包含一個TreeSet

實施例內此指數:

Name Column: 
Emma 
John 
Doe 
Emma 
Walker 
Emma 
Doe 

HashMap(Emma) -> 0, 3, 5 
private void buildIndex() 
    { 
     if (monitorModel.getMessageIndex() == null) 
     { 
      ArrayList<HashMap<String, TreeSet<Integer>>> messageIndex = new ArrayList<>(filterableColumn.length); 
      for (int i = filterableColumn.length; i >= 0; i--) 
      { 
       HashMap<String, TreeSet<Integer>> hash = new HashMap<>(); 
       messageIndex.add(hash); 
      } 
      // create index for every column 
      for (int i = monitorModel.getParser().getMyMessages().getMessages().size() - 1; i >= 0; --i) 
      { 
       TreeSet<Integer> tempList; 

       for (int j = 0; j < filterableColumn.length; j++) 
       { 
        String value = StringPool.getString(getValueAt(i, j).toString()); 
        if (!messageIndex.get(j).containsKey(value)) 
        { 
         tempList = new TreeSet<>(); 
         messageIndex.get(j).put(value, tempList); 
        } 
        else 
        { 
         tempList = messageIndex.get(j).get(value); 
        } 

        tempList.add(i); 
       } 
      } 
      monitorModel.setMessageIndex(messageIndex); 
     } 
    } 

將該溶液使用500MB堆大小這是不可能的,我怎麼可以優化該代碼?

回答

1

500MB堆大小這是不可能的

我嚴重懷疑它僅使用多,如果你有4個十億字符串。我懷疑你在那個時候停止了申請。

如果你有「4.000.000.000字符串數據」,那麼這將使用每串約100字節的集合存儲(假設字符串是短)

這意味着你需要400 GB的內存。使這個更高效且可行的唯一方法是使用內存映射文件。你可以很容易地用這種方式容納這麼多的數據。

另一方面,如果您的意思是400萬,而不是40億,那麼500 MB的大小是相當合理的。如果現在500 MB的成本大約是10美元,我不會擔心。

+0

對不起,我有4.000.000的數據,但只有10%是唯一的。 – flatronka 2012-08-09 08:58:07

+0

所以你正在浪費高達10美元的內存。使用內存映射文件可以使效率更高,並將堆用到少於1 MB。然而,複雜性不太值得。恕我直言。 – 2012-08-09 09:02:39

+1

如果你想看看使用內存映射文件來獲得想法的庫... https://github.com/peter-lawrey/Java-Chronicle我已經使用類似於這樣的庫來加載40億行Java中的數據。 – 2012-08-09 09:05:32