我正在使用Reflector 查看Roslyn 2012年9月的CTP,我注意到SlidingTextWindow类具有以下内容:
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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我相信这个类的目的是提供对输入文本的子串的快速访问,通过使用char[] characterWindow,一次从2048个字符开始(尽管characterWindow可能会增长).我相信这是因为获取字符数组的子字符串比使用字符串更快,正如Eric Lippert 似乎在他的博客上指出的那样.
在SlidingTextWindow每个时间类实例化Lexer类实例化,这恰好每次调用SyntaxTree.ParseText.
我不明白该arrayPool领域的目的.它在此类中的唯一用法是在构造函数和Dispose方法中.在调用时SyntaxTree.ParseText,似乎只创建了一个Lexer类和SlidingTextWindow类的实例.通过在characterWindow放置实例时排队并通过尝试在characterWindow创建实例时将队列出列来获得什么优势?
也许罗斯林团队的某些人可以帮助我理解这一点?
Eri*_*ert 17
优点是收集压力降低,这对整体性能有积极影响.
.NET垃圾收集器当然是一个通用的垃圾收集器.编译器和IDE的分配和对象生存期模式与平均业务线应用程序的模式完全不同,并且它们倾向于以不寻常的方式强调GC.
如果您在整个Roslyn中查看,有许多地方可以缓存小型数组并在以后重新使用,而不是让GC将它们识别为短期垃圾并立即回收它们.经验实验表明,这可以带来可衡量的性能提升.
我不建议您在自己的应用程序中这样做,除非您的分析表明您在收集压力上存在可衡量的性能问题.对于绝大多数应用程序而言,GC的调整非常好,并且汇集策略的好处不值得花费相当大的成本.
| 归档时间: |
|
| 查看次数: |
548 次 |
| 最近记录: |