2011-10-25 46 views
15

這可能似乎是一個討厭的事情,要求 但爲什麼我們有如此短的列表中的對象數量的限制。C#中的列表大小限制#

我寫了下面的代碼在C#

List<int> test = new List<int>();    
    long test1 = 0; 
    try 
    { 
     while (true) 
     { 
      test.Add(1); 
      test1++; 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(test1 + " | " + ex.Message); 
    } 

和測試列表大小列表的大小隻能是134217728

是不是不公平:(???什麼是另一種方法,如果我想要添加對象甚至超過'整數'限制(我的意思是對象數量> 2^32)???

+4

這不是圖靈機,電腦有限制。問題是什麼? –

+1

檢查這一個:http://stackoverflow.com/questions/3906891/what-is-the-max-limit-of-data-into-liststring-in-c –

+2

你想要做什麼> 2^32對象? – stukselbax

回答

52

A List<int>支持int[]。您將盡快更大的支持數組不能分配失敗 - 並且牢記:

  • 有一個2GB的每個對象限制在CLR即使是在64位(編輯:作爲.NET 4.5,這對於64位CLR可以避免 - 參見<gcAllowVeryLargeObjects>
  • 該列表將嘗試分配大於其立即需要的支持數組,以便容納稍後的Add請求而不用重新分配。
  • 在重新分配期間,舊的新陣列必須有足夠的總內存。

Capacity設置爲一個將使背襯陣列接近理論極限的值可能會得到比自然增長更高的截止點,但這個極限肯定會出現。

期待約2 元素(536,870,912)的限制 - 我微微一驚你還沒有成功地超越134217728。你有多少內存?你使用的是什麼版本的.NET,以及什麼架構? (對於32位CLR,每個對象的限制可能是1GB,我記不得了)

請注意,即使每個對象的限制不是問題,只要您得到高於2 您遇到問題的元素尋址那些元素直接與List<T>,因爲索引器需要int值。

基本上,如果你想要一個包含多於int.MaxValue元素的集合,你需要編寫自己的,可能使用多個後備數組。你可能想要明確禁止移除和任意插入:)

+0

列表支持int []?意味着列表不是一個列表,它的一個數組和列表中的添加和刪除相對於列表而言是相當昂貴的。我對嗎? (假設'分配支持的數組'可能是當前列表大小的一些倍數,以避免分配太多,而'添加') 此外,與此,有什麼區別列表和int [],我很樂意閱讀如果你可以分享一些詳細的內部筆記。 – Umer

+6

@Umer:該文檔使其合理清晰:「'List '類是'ArrayList'類的通用等價物,它使用一個大小根據需要動態增加的數組實現'IList '通用接口。當你說這是「不是一個清單」 - 這取決於你的意思是「一個清單」。這不是*鏈接*列表 - 如果你想要其中的一個,你想使用'LinkedList '。 'List '與數組之間的主要明顯區別是數組總是有固定的大小,而'List '可以增長和縮小。 –

+2

不斷增長和萎縮必須適當地重新分配,但從API的角度來看,您仍然在處理相同的「列表」。 –

6

這是一個令人難以置信的天真(而且未經測試)的實現BigList而不是整數。我在5分鐘左右寫完了,它沒有實現枚舉或者ilist,b它顯示了其他答案中提到的分區。是的,這是在VB中,處理它:)

這將需要一些非常認真的工作和調整之前它實際可用,但它說明了這個想法。

Public Class BigList(Of T) 
    Private mInternalLists As List(Of List(Of T)) 
    Private mPartitionSize As Integer = 1000000 

    Private mSize As Long = 0 

    Public Sub New() 
     mInternalLists = New List(Of List(Of T)) 
    End Sub 

    Public Sub Add(Item As T) 
     mSize += 1 

     Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize) 

     Dim Partition As List(Of T) 
     If mInternalLists.Count < PartitionIndex Then 
      Partition = New List(Of T) 
      mInternalLists.Add(Partition) 
     Else 
      Partition = mInternalLists(PartitionIndex) 
     End If 
     Partition.Add(Item) 
    End Sub 

    Default Public ReadOnly Property Item(Index As Long) As T 
     Get 
      Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize) 
      Dim Partition As List(Of T) 
      If mInternalLists.Count < PartitionIndex Then 
       Throw New IndexOutOfRangeException 
      Else 
       Partition = mInternalLists(PartitionIndex) 
      End If 

      Return Partition(CInt(mSize Mod mPartitionSize)) 
     End Get 
    End Property 
End Class 
0

我沒有測試它,但由於它的實施類型LinkedList<T>應該給你添加更多的元素,而不是List<T>的可能性。但要注意它的缺點(例如調用Count)。

1

列表限制爲〜536870912個字節

你加入整數(我的機器(32位的Win7,.NET 4.0)1/2 MB上)(各4個字節),所以上限爲字節限制/ 4(〜 134,217,727)