2013-04-30 51 views
0

在我的程序中,我執行一些任務,通過MyParameter對象(我調用doTask(MyParameter parameter)來運行任務)進行參數化。整個程序中的唯一任務

從開始到節目結束,我可以創造很多任務(至少有幾百萬),但我想運行一次他們每個人(如果任務已經執行,則方法不執行任何操作)

目前,我使用的是HashSet來存儲已經執行的任務的MyParameter對象,但如果MyParameter對象是100字節,如果我在我的程序10M任務運行時,它是1GB至少在內存中......)

我該如何優化,儘量少使用內存?

非常感謝球員

+0

你的任務是否並行運行?難道你不能創建 - 執行 - 銷燬? – fotanus 2013-04-30 23:04:53

+0

爲什麼需要在任務後存儲MyParameter對象?他們是否包含任何結果?如果你現在最關心的是使用更少的內存,你不能只是序列化MyParameter對象並將它們寫在磁盤或數據庫中嗎? – GameDroids 2013-04-30 23:13:31

回答

0

一個TreeSet會給你稍好內存性能比HashSet的,在日誌(n)的查找成本。

您可以使用NoSql鍵值存儲,如CassandraLevelDB,它們本質上是外部哈希表。

您或許可以壓縮MyParameter表示法,但如果它現在只有100bytes,那麼我不知道您能夠獲得的小小多少。

1

如果您只需要知道是否已經處理了某個特定的MyParameter,請將其替換爲HashSet並使用BitSet

基本上,如果你需要知道的是一個特定的MyParameter是否完成與否,則存儲在集合整個MyParameter是矯枉過正 - 你只需要存儲一個比特,其中0指「未完成」和1表示「完成」。這正是BitSet的設計目的。

您的MyParameter值的哈希大概是獨一無二的,否則您目前使用HashSet的方法是毫無意義的。如果是這樣,則可以使用每個MyParameterhashCode()作爲位集合的索引,使用相應位作爲給定的MyParameter是否完成的指示符。

這可能沒有太大意義,所以下面是一個基本的實現。 (隨意替代for循環,numParametersgetParameter()等有什麼,那就是你實際使用來產生MyParameter S)

BitSet doneSet = new BitSet(); 

for (int i = 0; < numParameters; ++i) { 
    MyParameter parameter = getParameter(i); 

    if (!doneSet.get(parameter.hashCode())) { 
     doTask(parameter); 
     doneSet.set(parameter.hashCode()); 
    } 
} 

這種方法的內存使用量是BitSet怎麼有點偶然在內部實現,但我希望它比將所有MyParameters存儲在HashSet中顯着更好。

如果,事實上,你需要掛到您的MyParameter對象,一旦你處理它們,因爲它們含有處理的結果,那麼你可以通過可能存儲在HashSetMyParameter而造成的部分節省空間(如果這樣的事情是可能的 - 你的問題沒有說清楚)。

另一方面,如果您確實需要完整處理每個MyParameter,那麼您已經完成了幾乎所有可以完成的工作。您可以通過將它們存儲爲MyParameters(避免使用HashSet固有的一些內存開銷)的向量(即可擴展陣列)來做一些更好的內存記憶方式,但這會因時間而導致速度損失需要擴展矢量和一個O(n)的搜索時間。

+0

我不需要已經計算好的'MyParameter'的值 我可以看到Bitset的唯一問題是碰撞問題。 但在其他方面,這是一個好主意:) – Nisalon 2013-05-01 08:57:24

+0

正如我在答案中所暗示的那樣,我假設你非常確信會有很少的散列衝突,否則你可能不會使用'HashSet'(因爲它的性能依賴於相對較少的碰撞)。很難說如果不知道更多關於你的數據的信息,但你應該(理論上)能夠爲你的MyParameter類派生一個最優化的hashCode()實現,以減少(甚至消除)碰撞風險。 – Mac 2013-05-01 20:54:42

相關問題