2013-10-31 47 views
5

在「C#深入」由Jon飛碟雙向,我讀取(第511章):陣列必須在CLR直接支持

所有的數組從System.Array的派生,而他們是唯一收藏直接支持CLR(我的重點)。

我想知道這意味着什麼,特別是與沒有這種支持的類型有關。 所有沒有這種支持的類型都是由CLR在解釋IL時完成的類型組合而成的?沒有CLR「知道」這種支持的類型?

另外在p。 512本書:

C#編譯器以多種方式內置了對數組的支持。

這是否在某種程度上涉及到直接支持數組類型的類型在CLR或者是這兩種不同的東西完全?

+0

當Skeet先生本人可以提供更好的答案時,似乎很難回答...... :) –

+2

看看[CIL指令列表](http://en.wikipedia.org/wiki/List_of_CIL_instructions )。處理數組有很多操作碼,但沒有涉及其他集合的操作碼。 – tom

回答

7

如上所述,數組存在於CLR的深處。有IL指令與它們進行交互(ldelem.*/stelem.*)。它們預先通用泛型,並允許根據需要創建不同類型的數組。對於其他集合類型,情況並非如此 - 例如,List<T>是在數組之上存在的包裝。 CLR不需要任何關於List<T>的特殊知識 - 只需定期訪問現有數組的內容即可,或者分配新數組。另一種主要的收集形式是鏈接列表(以及類似的;樹等) - 但是這些並不需要特別的支持 - 這些只是與引用連接在一起的對象。

4

是的,編譯器,抖動和CLR的三元組有很多內置的數組知識。這對於任何語言運行時都非常重要,它不能忽略處理器的功能。爲了使代碼高效地運行,它必須映射到處理器可以做得好的地方。

這不是很多,處理器是相當簡單的設備。他們沒有真正支持你喜歡在程序中使用的數據結構。語言和運行時的設計方式顯示了許多潛在的處理器實現細節。

例如,存在堆棧的概念無處不在。一個處理器可以通過堆棧指針直接訪問的少量內存。這就是爲什麼C#語言幾乎與任何語言一樣在方法內部具有局部變量的概念。這是一個將被存儲在堆棧上的變量。處理器還強烈支持使用返回單個值的參數調用方法的概念,這些參數在任何語言中都是通用的。分配給堆棧的少量內存給這個站點命名。

值類型是底層處理器細節的另一個.NET示例。它們直接映射到處理器在處理值時所擅長的內容。例如,int直接映射到處理器寄存器。 Float和double直接映射到處理器存儲這些值的能力,並使用這兩種類型執行浮點指令。

而陣列是處理器可以支持的唯一的數據結構。非常簡單,一個內存塊和一個訪問內存的指針。Very在.NET中進行了大量優化,使其儘可能高效。特別向「vector」點頭,這是一種專門處理的數組類型。起始索引爲0的一維數組,直接映射到處理器支持的數組類型。您將在C#中獲得一個帶有type[]聲明的向量。你也可以看到數組的限制,.NET使得如果非常難以創建一個起始索引不是0的數組。索引這樣一個數組的代價很昂貴,因爲它需要額外的減法來映射內存塊的索引。數組索引檢查是優化的另一個強大目標,邊界檢查是昂貴的。許多內置於抖動的智能識別循環無法將數組索引超出範圍,從而可以完全消除索引檢查。

任何數據結構都需要在處理器支持之上構建,僅用於裸陣列。這就是爲什麼你在.NET集合類中發現完成的原因。由於CLR或抖動沒有額外的幫助,因爲他們可以做得很少,以使其更快。也是這些集合類都是在矢量數組之上構建的原因。像列表<>,而不是類似於您在數據算法教科書中看到的那種列表,實際上是一個數組。或字典<>,數組的對映,但仍與他們一起實施。

+0

謝謝你這個詳盡的答案。使概念更加清晰。 – bump