2015-09-17 22 views
7

Tôi đang nhìn vào việc thực hiện Roslyn ObjectPool (https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/SharedCollections/ObjectPool%601.cs) và tôi không hiểu tại sao họ không đơn giản chọn để có một mảng T mà thay vào đó bọc T bên trong một cấu trúc?Roslyn ObjectPool struct wrapper

[DebuggerDisplay("{Value,nq}")] 
private struct Element 
{ 
    internal T Value; 
} 
... 
private readonly Element[] _items; 

Mục đích của việc này là gì?

Trả lời

5

Đây là một thủ thuật phổ biến để tránh các vấn đề về hiệu năng khi đặt các mục mảng là loại tham chiếu. Mảng là biến thể trên CLR (và trên JVM). Bạn có thể viết số string vào một số object[]. Điều này đòi hỏi một kiểm tra thời gian chạy mà bạn không thực sự lưu trữ một chuỗi vào một SomethingElse[]. Với thủ thuật loại giá trị đó, nó không cần thiết để thực hiện kiểm tra đó khi chạy.

+0

Nhưng 'ObjectPool' trên đó không đặt bất kỳ phần tử nào vào mảng. Nó dựa trên thực tế là mảng của struct được khởi tạo với các cá thể struct zeroed. –

+0

Vâng, * cái gì đó * sẽ đặt 'Giá trị'. Điểm gì nếu không có gì bao giờ đặt giá trị đó ?! Mã đó không được hiển thị ở đây. – usr

+0

Có một số mã đặt trường 'Giá trị'. Nhưng không có gì ghi đè lên phần tử trong một mảng. Cho rằng 'Giá trị' là một trường, Không có kiểu kiểm tra nào trong thời gian chạy. nó làm mất hiệu lực câu trả lời của bạn. Phải không? –

1

Tôi tin rằng đó là vì lý do hiệu suất. Mảng cấu trúc là một người bạn để thu gom rác như trái ngược với mảng của lớp.

Từ 5 Tips and Techniques for Avoiding Automatic GC Collections

Với một loạt các trường lớp, GC phải kiểm tra từng mục trong mảng đó để xem nếu nó là một đối tượng sống hay không (điều này cũng đúng đối với bộ sưu tập chung, sử dụng mảng nội bộ). Với một mảng gồm các cấu trúc , GC chỉ xem xét nếu mảng đó vẫn là đối tượng trực tiếp, vì cấu trúc không thể là rỗng (điều này đúng cho cả cấu trúc không rõ ràng, chỉ sử dụng cơ chế theo dõi nội bộ để xác định độ rỗng). Vì vậy, đó là khả năng hàng ngàn hoặc thậm chí hàng triệu của các mục mà GC không cần phải kiểm tra khi một bộ sưu tập chạy!

+0

Nếu đó là sự thật CLR sẽ chỉ luôn luôn quấn tất cả các phần tử mảng và không cần phải GC chúng ... Ngay cả một mảng các cấu trúc phải được đi qua nếu nó giữ tài liệu tham khảo. – usr

+0

@usr Tôi thấy bạn đến từ đâu. Ngay cả khi tôi vẫn còn hoài nghi khi lần đầu tiên tôi đọc bài báo. Có lẽ tác giả có nghĩa là nó chỉ có nghĩa là một mảng cấu trúc không chứa bất kỳ tham chiếu nào.Chúng tôi đã liên hệ với tác giả để biết thêm chi tiết. –

+0

GC chỉ có thể bỏ qua mảng các loại giá trị nếu chính loại đó không chứa tham chiếu. Nếu không, nó vẫn phải đi qua mảng. –