2009-04-24 33 views
85

有沒有人在C#編程時使用過stackalloc?我知道這是幹什麼的,但唯一一次出現在我的代碼中是偶然的,因爲例如,當我開始輸入static時,Intellisense會提示它。`stackalloc`關鍵字的實際用法

雖然它與stackalloc的使用場景無關,但我實際上在我的應用程序中執行了大量的傳統互操作,所以我現在可以隨時使用unsafe代碼。但我通常想辦法完全避免unsafe

由於.Net中單個線程的堆棧大小爲〜1Mb(糾正我,如果我錯了),我更加保留使用stackalloc

是否有一些實際情況下,可以說:「這是正確的數據和處理量,我去不安全和使用stackalloc」?

+2

只是注意到`System.Numbers`使用它很多https://referencesource.microsoft.com/#mscorlib/system/number.cs,86404b606ba1649f – Slai 2016-10-27 12:18:40

回答

90

使用stackalloc的唯一原因是性能(用於計算或互操作)。通過使用stackalloc而不是堆分配數組,您可以創建更少的GC壓力(GC需要運行更少),不需要固定陣列,分配速度比堆陣列快,它會自動釋放方法退出(堆分配數組只在GC運行時解除分配)。此外,通過使用stackalloc而不是本機分配器(如malloc或.Net等價物),您還可以在範圍退出中獲得速度和自動釋放。

性能方面,如果使用stackalloc,由於數據的局部性,可以大大增加CPU高速緩存命中的機會。

20

stackalloc僅與不安全的代碼相關。對於託管代碼,您無法決定分配數據的位置。值類型在默認情況下分配在堆棧上(除非它們是引用類型的一部分,在這種情況下,它們分配在堆上)。引用類型分配在堆上。

普通的vanilla .NET應用程序的默認堆棧大小爲1 MB,但您可以在PE標頭中更改它。如果你明確地啓動線程,你也可以通過構造函數重載設置不同的大小。對於ASP.NET應用程序,默認的堆棧大小僅爲256K,如果要在兩種環境之間切換,請記住這一點。

+0

是否有可能從Visual Studio更改默認堆棧大小? – configurator 2010-09-17 19:12:24

+0

@configurator:據我所知。 – 2010-09-17 19:53:39

27

我已經使用stackalloc爲[near]實時DSP工作分配緩衝區。這是一個非常具體的情況,表現需要儘可能一致。請注意,一致性和整體吞吐量之間存在差異 - 在這種情況下,我並不關心堆分配速度太慢,只是在程序中的那個點上存在非確定性的垃圾收集。我不會在99%的情況下使用它。