2009-04-24 62 views
85

Có ai từng thực sự sử dụng stackalloc trong khi lập trình trong C# không? Tôi nhận thức được những gì đang làm, nhưng lần duy nhất nó xuất hiện trong mã của tôi là do tai nạn, bởi vì Intellisense gợi ý nó khi tôi bắt đầu gõ static, ví dụ.Sử dụng thực tế từ khóa `stackalloc`

Mặc dù nó không liên quan đến các tình huống sử dụng của stackalloc, tôi thực sự thực hiện một số lượng đáng kể tương tác kế thừa trong ứng dụng của mình, vì vậy, bây giờ tôi có thể sử dụng mã unsafe. Nhưng tuy nhiên tôi thường tìm cách tránh hoàn toàn unsafe.

Và vì kích thước ngăn xếp cho một chuỗi duy nhất trong .Net là ~ 1Mb (đúng với tôi nếu tôi sai), tôi thậm chí còn được dành nhiều hơn khi sử dụng stackalloc.

Có một số trường hợp thực tế mà người ta có thể nói: "đây chính xác là lượng dữ liệu phù hợp và xử lý để tôi không an toàn và sử dụng stackalloc"?

+2

chỉ nhận thấy rằng 'System.Numbers' sử dụng nó rất nhiều https://referencesource.microsoft.com/#mscorlib/system/number.cs,86404b606ba1649f – Slai

Trả lời

90

Lý do duy nhất để sử dụng stackalloc là hiệu suất (cho tính toán hoặc tương tác). Bằng cách sử dụng stackalloc thay vì mảng phân bổ heap, bạn tạo áp lực GC ít hơn (GC cần chạy ít hơn), bạn không cần phải ghim mảng xuống, phân bổ nhanh hơn mảng heap, nó được tự động giải phóng thoát phương thức (mảng được phân bổ heap chỉ được deallocated khi GC chạy). Ngoài ra, bằng cách sử dụng stackalloc thay vì một trình cấp phát gốc (như malloc hoặc .Net tương đương), bạn cũng đạt được tốc độ và thỏa thuận tự động khi thoát khỏi phạm vi.

Hiệu suất khôn ngoan, nếu bạn sử dụng stackalloc bạn sẽ tăng khả năng truy cập bộ nhớ cache trên CPU do vị trí dữ liệu.

+19

Địa phương của dữ liệu, điểm tốt! Đó là những gì bộ nhớ quản lý sẽ hiếm khi đạt được khi bạn muốn phân bổ một số cấu trúc hoặc mảng. Cảm ơn! – Groo

+16

Phân bổ heap thường nhanh hơn đối với các đối tượng được quản lý hơn là không được quản lý vì không có danh sách miễn phí để duyệt; CLR chỉ tăng con trỏ heap. Đối với địa phương, phân bổ tuần tự có nhiều khả năng kết thúc colocated cho các quy trình được quản lý lâu dài do nén chặt. –

20

stackalloc chỉ phù hợp với mã không an toàn. Đối với mã được quản lý, bạn không thể quyết định vị trí phân bổ dữ liệu. Các kiểu giá trị được phân bổ trên stack theo mặc định (trừ khi chúng là một phần của kiểu tham chiếu, trong trường hợp này chúng được phân bổ trên vùng heap). Các kiểu tham chiếu được cấp phát trên heap.

Kích thước ngăn xếp mặc định cho ứng dụng .NET thuần túy là 1 MB, nhưng bạn có thể thay đổi điều này trong tiêu đề PE. Nếu bạn đang bắt đầu chủ đề một cách rõ ràng, bạn cũng có thể đặt kích thước khác thông qua quá tải của hàm tạo. Đối với các ứng dụng ASP.NET, kích thước ngăn xếp mặc định chỉ là 256K, đó là điều cần lưu ý nếu bạn đang chuyển đổi giữa hai môi trường.

+0

Có thể thay đổi kích thước ngăn xếp mặc định từ Visual Studio không? – configurator

+0

@configurator: Không xa như tôi biết. –

27

Tôi đã sử dụng stackalloc để phân bổ bộ đệm cho công việc DSP gần [thời gian thực]. Đó là một trường hợp rất cụ thể trong đó hiệu suất cần phải nhất quán nhất có thể. Lưu ý có sự khác biệt giữa tính nhất quán và thông lượng tổng thể - trong trường hợp này tôi không quan tâm đến việc phân bổ heap quá chậm, chỉ với tính không xác định của việc thu gom rác tại thời điểm đó trong chương trình. Tôi sẽ không sử dụng nó trong 99% trường hợp.

Các vấn đề liên quan