我看Roslyn September 2012 CTP與反射,我注意到SlidingTextWindow類有以下幾點:爲什麼在這種情況下使用ConcurrentQueue?
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;
}
// ...
}
我相信這個類的目的是提供輸入文本的子快速訪問,通過使用char[] characterWindow
,一次從2048個字符開始(儘管characterWindow
可能增長)。我相信這是因爲字符數組的子字符串比字符串更快,正如Eric Lippert seems to indicate on his blog。
每次Lexer
類實例化時,SlidingTextWindow
類都會實例化,每次調用SyntaxTree.ParseText
時都會發生這種類。
我不明白arrayPool
字段的用途。它在這個類中的唯一用法是在構造函數和Dispose方法中。當致電SyntaxTree.ParseText
時,似乎只創建了Lexer
類和SlidingTextWindow
類的一個實例。當一個實例處理時排隊characterWindow
,並且在創建一個實例時嘗試將一個characterWindow
排隊,會帶來什麼好處?
也許有人來自羅斯林團隊可以幫助我理解這一點?
是否爲減少內存或提高速度(或兩者)的主要目的完成小陣列的緩存?是否有如此多的編譯器/ IDE所必需的數組,每次創建一個新數組都會佔用大量內存?或者是否會通過使用線程安全隊列並使多個線程作用於陣列來提高速度? – cubetwo1729
主要是速度和響應速度。 GC在性能方面很有意思 - 它幾乎可以免費分配內存,但當GC運行時,您需要付出代價。在某些情況下,如果在編寫代碼的同時在編輯器中鍵入字符時發生運行,則GC對鍵入有明顯的影響,並且無法執行完全併發的GC。 我確實想強調Eric所說的 - 我們只在我們看到配置文件中出現特定分配時才這樣做。除非我們知道這是特定位置的特定問題,否則我們不會這樣做。 –
@JasonMalinowski挑選'ConcurrentQueue'而不是'ConcurrentBag'的任何特定原因? – CodesInChaos