Tôi đang tìm kiếm tại Roslyn September 2012 CTP với Reflector, và tôi nhận thấy rằng lớp SlidingTextWindow có sau đây:Tại sao sử dụng ConcurrentQueue trong trường hợp này?
internal sealed class SlidingTextWindow : IDisposable
{
private static readonly ConcurrentQueue<char[]> arrayPool = new ConcurrentQueue<char[]>();
private int basis;
private readonly LexerBaseCache cache;
private char[] characterWindow;
private int characterWindowCount;
private int characterWindowStart;
private int offset;
private readonly IText text;
private readonly int textEnd;
public SlidingTextWindow(IText text, LexerBaseCache cache)
{
this.text = text;
this.basis = 0;
this.characterWindowStart = 0;
this.offset = 0;
this.textEnd = text.Length;
this.cache = cache;
if (!arrayPool.TryDequeue(out this.characterWindow))
{
this.characterWindow = new char[2048];
}
}
public void Dispose()
{
arrayPool.Enqueue(this.characterWindow);
this.characterWindow = null;
}
// ...
}
tôi tin rằng mục đích của lớp này là để cung cấp cho chuỗi con của chuỗi nhập truy cập nhanh, bằng cách sử dụng char[] characterWindow
, bắt đầu với 2048 ký tự cùng một lúc (mặc dù characterWindow
có thể phát triển). Tôi tin rằng điều này là bởi vì nó là nhanh hơn để có chất nền của mảng ký tự hơn của chuỗi, như Eric Lippert seems to indicate on his blog.
Lớp SlidingTextWindow
được khởi tạo mỗi khi lớp Lexer
được khởi tạo, điều này xảy ra mỗi cuộc gọi đến SyntaxTree.ParseText
.
Tôi không hiểu mục đích của trường arrayPool
. Cách sử dụng duy nhất của nó trong lớp này là trong phương thức khởi tạo và Vứt bỏ. Khi gọi SyntaxTree.ParseText
, có vẻ như chỉ có một phiên bản của lớp Lexer
và của lớp SlidingTextWindow
được tạo. Lợi thế nào đạt được bằng cách enqueuing các characterWindow
khi một trường hợp được xử lý và bằng cách cố gắng dequeue một characterWindow
khi một thể hiện được tạo ra?
Có lẽ ai đó từ nhóm Roslyn có thể giúp tôi hiểu điều này?
Bộ nhớ đệm của các mảng nhỏ có được thực hiện cho mục đích chính là giảm bộ nhớ hoặc tăng tốc độ (hoặc cả hai)? Có phải là trường hợp với rất nhiều mảng cần thiết cho một trình biên dịch/IDE, tạo ra một mảng mới mỗi lần sẽ mất rất nhiều bộ nhớ? Hoặc sẽ có một sự gia tăng tốc độ bằng cách sử dụng một hàng đợi an toàn thread và có nhiều chủ đề hành động trên các mảng? – cubetwo1729
Chủ yếu là tốc độ và khả năng phản hồi. GC là thú vị khi nói đến hiệu suất - nó làm cho phân bổ bộ nhớ gần như miễn phí, nhưng bạn phải trả chi phí sau khi GC phải chạy. Và trong một số trường hợp, GC có tác động đáng chú ý khi nhập nếu nó xảy ra để chạy khi bạn nhập một ký tự trong trình chỉnh sửa trong khi viết mã và không thể thực hiện GC đồng thời hoàn toàn. Tôi muốn làm nổi bật những gì Eric đã đề cập - chúng tôi chỉ làm điều này khi chúng tôi thấy phân bổ cụ thể xuất hiện trên tiểu sử. Chúng tôi không làm những việc như thế này cho đến khi chúng tôi biết đó là một vấn đề cụ thể ở một địa điểm cụ thể. –
@JasonMalinowski Bất kỳ lý do cụ thể nào để chọn 'ConcurrentQueue' thay vì' ConcurrentBag'? – CodesInChaos