2010-09-02 61 views
8

我想找到和重複使用(如果可能的話),它具有以下屬性的映射實現:自適應地圖Scala中(或Java)保留插入順序

  1. 雖然條目的數量很小,比如底層存儲應該像這樣[array0,val0,key1,val1,...]這樣的數組完成。這種存儲方案避免了許多小的Entry對象,並提供了極快的查找速度(即使它們是順序掃描!)。在現代CPU的由於CPU的高速緩存不被無效和缺乏指向堆的指針間接。

  2. 地圖應該保持鍵/值對插入順序不分類似的條目數來的LinkedHashMap

我們對巨大的(百萬節點/邊緣)的內存中表示工作Scala中的圖形並且具有這樣的Map將允許我們以更有效的方式存儲節點/邊緣屬性以及每個節點的邊緣,對於具有少量屬性或鄰居的99%以上的節點和邊緣,同時保持兩者的按時間順序的插入順序屬性和邊緣。

如果有人知道具有這些特性的Scala或Java地圖,我會非常感激。

感謝名單

+1

作爲參考,我注意到OP沒有找到我的解決方案令人滿意,並要求我將其刪除。簡而言之,這個想法是將所有東西放在索引數組中,Fortran風格,但是在這個結構中寫出漂亮的包裝,這樣處理起來很愉快。這種方法的優點是速度非常快(由於主要是使用原語),並且自然保留了插入順序(因爲當您需要新條目時,只需將1添加到索引中)。 Fortran和C中的很多圖表工作都是通過這種方式完成的,但我同意我沒有確定所需的地圖。 – 2010-10-06 15:06:33

+0

由於您已經在考慮實施,爲什麼不寫自己的?在數組或者LinkedHashMap中編寫一個封裝器並不難。 – starblue 2010-10-06 19:20:57

+1

您正在使用您的收藏作爲特殊情況。因此你不應該打擾這種正常的儲蓄方式。創建自己的數據結構以獲得更高的性能會很有趣。你可以針對你的情況優化你的結構,因爲你似乎對你的圖形非常瞭解。所以你應該考慮樹木,列表等等,以獲得儘可能高的性能。也許你得到O(n * logn)或更少的runtine性能......;) – 2010-10-07 09:25:29

回答

0

下的java可以保持二維數組(電子表格)。我編寫了一個程序,它基本上定義了一個包含3個數據顏色的2維數組,以及3個用於查找數據的彩色數據庫。三個coloumns是testID,SubtestID和Mode。這允許我基本上通過testid和模式或任何組合來查找值,或者我也可以通過靜態放置來引用。該表在啓動時加載到內存中,並由程序引用。它可以無限擴展,並且可以根據需要添加新值。

如果您有興趣,我可以發佈一個代碼源示例今晚。

另一個想法可能是在程序中維護一個數據庫。數據庫旨在組織大量數據。

+0

這個答案沒有解決我的具體狹義問題:自適應地圖。我們確實考慮了其他圖表表示,但由於很多技術原因我不能進入,我們必須保持圖形節點,邊緣等(所有原子真的)都必須具有其自己的屬性映射對象的「本地化」設計。再一次,我想避免一個常見的模式,即爲小型(<32條入口映射)使用許多小型的Map.Entry類對象來保存內存並保持CPU上的緩存局部性(即通過小型陣列進行掃描總是更快練習比遵循一堆堆指針)。 – 2010-10-07 21:38:42

1

儘管我不知道任何完全符合您要求的實施方式,但您可能有興趣在Jakarta Commons圖書館中偷看Flat3Mapsource)。不幸的是,雅加達圖書館相當過時(例如,在最新的穩定版本中不支持泛型,雖然它很有希望看到這種情況正在變化),我通常更喜歡Google Collections,但它可能是值得的您有時間瞭解Apache如何實現這些功能。

不幸的是,Flat3Map並沒有保留鍵的順序,但我對你的原始文章有一個建議。我不推薦使用並行數組,而是像[key0, val0, key1, val1, ...]那樣將鍵和值存儲在單個數組中。即一個數組[key0, key1, ...],另一個數組[val0, val1, ...]。通常我不是平行數組的支持者,但至少這樣你可以有一個K類型的數組,你的鍵類型和另一個類型V,你的值類型。在Java級別,由於您不能使用語法K[] keys = new K[32],因此它有自己的一套疣;相反,您需要使用a bit of typecasting

+0

現在這*是一種我正在尋找的答案。在我之前的工作中,我發現「扁平」映射(如apache ppl稱爲它們)僅在32或甚至64個條目之後變得比標準哈希映射慢,這可能是由於現代CPU在堆中具有非常好的核心緩存和指針間接引導導致內存失速。理想情況下,從「平坦」切換到標準地圖將基於可配置的閾值進行。我會加註這個答案,但是這將從未答覆的隊列中移除問題:-)我想讓問題突出一點時間。感謝您的回答。 – 2010-10-10 12:30:37

1

如果LinkedHashMap對您來說太慢,您是否使用探查器測量過?也許你不需要那張新地圖 - 不成熟的優化是所有邪惡的根源。 無論如何,在一秒鐘內處理數百萬或更多的數據,即使是最佳優化的地圖也可能太慢,因爲在這種情況下,每個方法調用都會降低性能。然後,您只需將Java集合中的算法重寫爲數組(即int - > object maps)即可。

+0

問題不在於速度,而在於速度,它也是分配,保留和GC化的小型Emtry對象的數量。 – 2010-10-12 20:22:53

+0

但分配時間加起來慢 - 分配較慢程序的對象越多,因此這一切都會降低到由分析器測量的性能。 – iirekm 2010-10-13 07:38:49

+0

今天大多數電腦都有4GB內存使用率優化很少有意義。但是,如果有,通常最好使用享元模式。一個例子可以在Java Swing的TreeModel中找到。而不是node.getAttribute(key)= node.attributeMap.get(key)使用類似node.getAttribute(key)= graph.attributeModel.getAttribute(node) – iirekm 2010-10-13 07:56:02