gpt4 book ai didi

c# - 为什么在这种情况下使用 ConcurrentQueue?

转载 作者:太空狗 更新时间:2023-10-29 19:57:07 56 4
gpt4 key购买 nike

我正在查看 Roslyn September 2012 CTP使用 Reflector,我注意到 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;
}

// ...
}

我相信此类的目的是通过使用 char[] characterWindow 提供对输入文本子字符串的快速访问,一次从 2048 个字符开始(尽管 characterWindow 可能会增长)。我相信这是因为获取字符数组的子字符串比获取字符串的子字符串更快,如 Eric Lippert seems to indicate on his blog .

SlidingTextWindow 类在每次 Lexer 类实例化时实例化,每次调用 SyntaxTree.ParseText 时都会实例化。

我不明白 arrayPool 字段的用途。它在此类中的唯一用法是在构造函数和 Dispose 方法中。调用 SyntaxTree.ParseText 时,似乎只创建了 Lexer 类和 SlidingTextWindow 类的一个实例。在处置实例时将 characterWindow 入队以及在创建实例时尝试将 characterWindow 出队有什么好处?

也许 Roslyn 团队的某个人可以帮助我理解这一点?

最佳答案

优点是减少了收集压力,这对整体性能有积极影响。

.NET 垃圾收集器当然是通用垃圾收集器。编译器和 IDE 的分配和对象生命周期模式与一般的业务线应用程序有很大不同,它们往往以不同寻常的方式对 GC 施加压力。

如果您纵观整个 Roslyn,就会发现很多地方都缓存了小数组并在以后重新使用,而不是让 GC 将它们识别为短暂的垃圾并立即回收它们。实证实验表明,这可以显着提高性能。

我不建议在您自己的应用程序中这样做,除非您的分析表明您在收集压力方面存在可衡量的性能问题。对于绝大多数应用程序,GC 都经过了很好的调整,池化策略的好处不值得付出可观的成本。

关于c# - 为什么在这种情况下使用 ConcurrentQueue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18429946/

56 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com