2012-07-07 47 views
2

我試圖做的事:如何在一個值中構建變量1到4字節的結構?

我想在RAM中存儲非常多的數據。爲了更快地存取和更少的內存佔用我需要使用結構值的數組:

MyStruct[] myStructArray = new MyStruct[10000000000]; 

現在我想要存儲的無符號整型值與MYSTRUCT一個,兩個,三個或四個字節。但它應該只使用盡可能少的內存量。當我將一個值存儲一個字節時,它應該只使用一個字節,依此類推。

我可以通過類來實現這個,但這不合適,因爲指向該對象的指針在64位系統上需要8個字節。所以最好爲每個數組條目存儲4個字節。但是我想在需要時只存儲/使用一個/兩個/三個字節。所以我不能使用一些奇特的課程。

我也不能使用一個數組與一個字節,一個數組與兩個字節等,因爲我需要的值的特殊順序。而且這些值非常混雜,因此在切換到另一個陣列時存儲額外的參考將無濟於事。

有沒有可能想要什麼或者是否只是存儲一個4字節的數組的唯一方法,無論我只需要存儲一個字節,兩個字節約60%的時間和三個字節約25%時間?

+1

你看着[StructLayoutAttribute(http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx)? – Oded 2012-07-07 21:47:48

+0

這對我的情況沒有幫助。我需要在一個結構中包含一個字節值,兩個字節值,三個字節值和四個字節值的結構。但是,當我僅存儲一個字節時,僅使用一個字節。我不知道StructLayoutAttribute如何提供幫助。 – Chris 2012-07-07 21:51:18

+0

哪個是您的主要目標,內存使用率較低還是訪問速度較快? – Dave 2012-07-07 21:52:08

回答

2

如果您願意犧牲一些額外的CPU時間並浪費每個存儲值的額外2位或4位,那麼您可以接近此要求。

您可以使用字節byte[]並將其與BitArray collection結合使用。在byte []中,您只需按順序存儲一個,兩個,三個或四個字節,並且在BitArray中以二進制形式表示(一對兩位),或者將一個位置1以表示一組新的字節或結束,但是你實現它)在你的數據數組中。

但是你可以得到這樣的記憶:

byte[] --> [byte][byte][byte][byte][byte][byte][byte]... 
BitArray --> 1001101... 

這意味着你有3個字節,1個字節,2個字節等存儲在您的字節數組值。

或者你也可以交替編碼您bitarray二進制對使它更小。這意味着你可以在你的實際數據字節中嘗試1.0625到1.25字節之間的空間。

這取決於你的實際數據(你MyStruct)如果這就夠了。如果您需要區分結構中哪些字節真正對應的值,則可以浪費BitArray中的一些額外位。

更新到你的O(1)要求:

使用另一種索引結構,這將存儲一個指數每N個元素,例如1000。然後你可以用指數234241例如接入項目爲

indexStore[234241/1000] 

,讓你元素234000的指數,那麼你只需要通過檢查BitArray那些幾百元計算元素234241確切的指標。

O(常量)被acheieved這樣,常量可以與主要指數的密度來控制的,當然你交易時間換空間。

6

這是不可能的。 CLR如何處理以下表達式?

myStructArray[100000] 

如果元素大小可變,CLR無法知道第100000個元素的地址。因此數組元素的大小始終是固定的。

如果您不需要O(1)訪問,可以實現在byte[]的頂部可變長度元素和自己搜索陣列。

您可以將列表拆分爲1000個子列表,它們是單獨打包的。這樣你平均可以獲得O(n/2000)的搜索性能。也許這在實踐中已經夠好了。

「打包」數組平均只能在O(n/2)中搜索。但是,如果您的部分數組的大小是1/1000的大小,它將變成O(n/2000)。您可以選取O(1)中的部分數組,因爲它們全部大小相同。

此外,您可以調整部分數組的數量,使它們單獨大小約爲1k個元素。那時,數組對象的開銷和對它的引用就消失了。這會給你O(1000/2 + 1)查找性能,我認爲是比O(n/2)相當改進。這是一個恆定查詢(具有很大的常量)。

+0

這就是我的問題。我現在想着用byte []自己構建我的數組。我會用一個字節的第一位來判斷是否有第二個字節,等等。但目前我需要O(1)訪問。循環遍歷整個陣列會給我帶來O(n/2)的訪問時間,我認爲。 – Chris 2012-07-07 22:35:12

+0

這是真實的,我相信這是不可能有在這種情況下時間和空間效率。您可以將列表拆分爲1000個子列表,這些子列表單獨打包。這樣你平均可以獲得O(n/2000)的性能。夠了嗎? – usr 2012-07-07 22:45:22

+0

目前我不能說,因爲我不認爲這將是O(N/2000)。當我擁有100億個物品時,將它們打包成1000個陣列,每個子列表剩下1000萬個物品。現在每個條目都有一個可變長度。我認爲現在重要的部分是「自己搜索陣列」部分。你有沒有其他的/更好的建議比我會這樣做(使用第一位來表明還有一個字節等)? – Chris 2012-07-07 23:03:48

1

你不能這樣做。

如果數據未排序,並沒有什麼更多的,你能說一下,那麼你不會是能夠做到你想要什麼。

簡單的場景:

array[3] 

應指向一些內存地址。但是,您如何知道array[0] - array[2]的尺寸?要以O(1)方式存儲這些信息,您只會浪費比您想要首先保存的更多內存。

你在開箱思考,這很好。但是,我的猜測是,這是你試圖擺脫的錯誤框。如果您的數據真的是隨機的,並且您希望直接訪問每個數組成員,則必須使用每個數字所需的MAXIMUM寬度。抱歉。

我有一個類似的情況,與具有長度比我需要存儲32位的更小的號碼。但他們都是固定的寬度,所以我能夠通過定製容器和一些位移來解決這個問題。

HOPE:

http://www.dcc.uchile.cl/~gnavarro/ps/spire09.3.pdf

也許你能理解它,然後你就可以不僅有8,16,24,每個號碼32位,但任何數量的大小...

0

我幾乎開始尋找一些像PkZip程序一樣的短字編碼變體。

甚至RLE編碼。

或者試着去了解你的數據的使用更好。等,如果這些是所有矢量或東西,然後有被禁止等,-1,-1某些組合,-1是基本上無意義的一個金融繪圖應用,因爲它表示數據外側在graphable範圍。如果你可以發現你的數據有些古怪,你可以通過爲不同的需求設置不同的結構來縮小規模。

相關問題