[英]java: sparse bit vector [closed]
TL; DR在這里用Java實現高效的稀疏BitSet實現
我知道這是一個“老”的問題,但我遇到了同樣的問題,我偶然發現了這篇文章。 雖然答案很好,但我最終並不滿意。 在進一步挖掘之后,我想我已經遇到了Java中稀疏BitSets問題的“權威”答案。
在本演示中 ,作者Bruce Haddon博士討論了他的研究人員為標准Java BitSet創建高內存效率和高性能替代品所做的努力。
他演示文稿的原始鏈接已經死了,但我聯系了Haddon博士並保留了代碼和演示文稿:
https://github.com/brettwooldridge/SparseBitSet
我不建議更高度地閱讀此演示文稿。 即使您對稀疏位集沒有興趣,它也是一個引人入勝的讀物,更多的是解決問題的本質......
如果它真的很稀疏(例如,小於1%的加載),那么使用由位索引索引的哈希表可能相當不錯; 如果該位分別為1或0,則只需要知道表中是否存在索引。
如果密度高達百分之幾,則可以使用由位索引除以64的哈希表,並在包含實際位的哈希表中存儲長字。 如果散列表包含用於int(N / 64)的值V並且(V >>(N mod 64))&1為真,則設置位N.
這兩個答案都假設您希望優化對位的隨機訪問。 如果要按索引優化對位的順序(或其他訪問),則可能需要稀疏矩陣結構,使用相同類型的低級位向量表示,具體取決於預期的密度。 請參見稀疏矩陣
colt庫具有稀疏矩陣(1D,2D和3D)。 它還有一個高效的BitVector,每個值1位,而不是boolean[]
8位。
但是,稀疏矩陣不直接支持位 - 只有雙精度和對象。 您可以通過將位索引maping到長索引(bitIndex>>6)
來包裝1D稀疏雙矩陣,因為每個long保持64位, 將檢索到的double轉換為原始long值,並使用位操作來訪問檢索到的long的位。 一點點工作,但遠不及自己實現稀疏矢量那么多。 一旦你的包裝器工作,你可能會避免將雙精度轉換為long,並使用雙1D稀疏矩陣的可用Colt源代碼作為起點實現一個真正的稀疏長1d矩陣。
編輯:更多信息。 假設所有位(長)最初為0,Colt向量/矩陣最初不需要存儲器用於存儲。將值設置為非零會占用內存。 將值設置回0會繼續消耗內存,但會定期回收零值的內存。
如果這些位真正稀疏,使得每個后備長值僅設置一個位,則存儲開銷將非常差,需要存儲每個實際位64位。 但是當你提到典型的情況是20-40%稀疏時,那么開銷會低得多,如果位聚集在范圍內,可能沒有浪費的存儲,例如0-100,然后是1000-1100和2000-2200(以十六進制表示的值。)總的來說,只有1/16的區域被分配給位,但是聚類意味着這些位被存儲而沒有浪費的空間。
您可以嘗試FastUtil的AVL樹圖 。
這里的聚會已經很晚了,但是這個問題的 PageRank 很高。 咆哮的Bitmap吃了不少這些用例。
CERN COLT廣泛用於向量和矩陣計算,並且具有稀疏矩陣,但不專門用於位向量。
http://acs.lbl.gov/software/colt/api/cern/colt/matrix/impl/SparseObjectMatrix1D.html
一個哈希表,僅僅存在或不存在密鑰告訴你什么? 那將是一個哈希集! 我對BitSet上的一個集合(甚至是一個哈希值)的性能持懷疑態度。 這實際上取決於速度或內存是否是主要驅動因素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.