내가 리플렉터와 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처럼 문자열보다 문자 배열의 부분 문자열을 취하는 것이 더 빠르기 때문입니다.
SlidingTextWindow
클래스는 Lexer
클래스가 인스턴스화 될 때마다 인스턴스화되며, SyntaxTree.ParseText
을 호출 할 때마다 발생합니다.
arrayPool
필드의 목적을 이해할 수 없습니다. 이 클래스의 유일한 용도는 생성자 및 Dispose 메서드입니다. SyntaxTree.ParseText
을 호출하면 Lexer
클래스와 SlidingTextWindow
클래스의 인스턴스가 하나만 생성 된 것으로 보입니다. 인스턴스가 삭제 될 때 을 대기열에 추가하고 인스턴스가 생성 될 때 characterWindow
을 대기열에서 제외하려고하면 어떤 이점이 있습니까?
아마도 Roslyn 팀의 누군가가 이것을 이해하는 데 도움이 될까요?
작은 배열의 캐싱은 메모리를 줄이거 나 속도를 높이는 것이 주 목적입니까? 컴파일러/IDE에 필요한 많은 배열이 있기 때문에 매번 새로운 배열을 만들면 많은 메모리가 필요합니까? 또는 스레드 안전 큐를 사용하고 배열에 여러 스레드가 작동하여 속도가 향상됩니까? – cubetwo1729
주로 속도와 응답 성. GC는 성능 측면에서 흥미 롭습니다. 메모리를 거의 무료로 할당 할 수 있지만 나중에 GC를 실행해야 할 때 비용을 지불하게됩니다. 그리고 어떤 경우에는 코드를 작성하는 동안 문자를 편집기에 입력하는 것처럼 실행되는 경우 GC가 완전히 동시 GC를 수행 할 수없는 경우 입력에 눈에 띄는 영향을줍니다. 에릭이 언급 한 것을 강조하고 싶습니다. 특정 할당이 프로필에 표시되는 것을 볼 때만 이것을 수행합니다. 특정 위치에서 특정 문제가 발생할 때까지는 이런 일을하지 않습니다. –
@JasonMalinowski 'ConcurrentBag'대신 'ConcurrentQueue'를 선택해야하는 구체적인 이유는 무엇입니까? – CodesInChaos