.NET内部StringBuilderCacheクラス構成の理解
-
21-12-2019 - |
質問
廃止された.NETアセンブリのいくつかを見ているときは、複数のフレームワークのメソッドで使用される興味深いStringBuilderCache
クラスに注目しました。
internal static class StringBuilderCache
{
[ThreadStatic]
private static StringBuilder CachedInstance;
private const int MAX_BUILDER_SIZE = 360;
public static StringBuilder Acquire(int capacity = 16)
{
if (capacity <= 360)
{
StringBuilder cachedInstance = StringBuilderCache.CachedInstance;
if (cachedInstance != null && capacity <= cachedInstance.Capacity)
{
StringBuilderCache.CachedInstance = null;
cachedInstance.Clear();
return cachedInstance;
}
}
return new StringBuilder(capacity);
}
public static void Release(StringBuilder sb)
{
if (sb.Capacity <= 360)
{
StringBuilderCache.CachedInstance = sb;
}
}
public static string GetStringAndRelease(StringBuilder sb)
{
string result = sb.ToString();
StringBuilderCache.Release(sb);
return result;
}
}
.
使用例使用例:string.Format
メソッドには、次のように検索できます。
public static string Format(IFormatProvider provider, string format, params object[] args)
{
...
StringBuilder stringBuilder = StringBuilderCache.Acquire(format.Length + args.Length * 8);
stringBuilder.AppendFormat(provider, format, args);
return StringBuilderCache.GetStringAndRelease(stringBuilder);
}
.
それはかなり賢く、私はそのようなキャッシングパターンについて覚えていますが、なぜMAX_BUILDER_SIZE
がとても小さいのだろうか?それを設定すると、2KBを設定しましょう、もはや良くないでしょうか?それは非常に小さいメモリオーバーヘッドを持つより大きなStringBuilder
インスタンスを作成するのを防ぐだろう。
解決
スレッドごとのキャッシュであるため、低い数が期待されています。リファレンスソースこのような質問は、コメントも表示されます。どちらのように見えます(編集編集):
// The value 360 was chosen in discussion with performance experts as a
// compromise between using as litle memory (per thread) as possible and
// still covering a large part of short-lived StringBuilder creations on
// the startup path of VS designers.
private const int MAX_BUILDER_SIZE = 360;
.
「VSデザイナー」は週のビットの不可解です。まあ、本当に、確かにこの作品はVisual Studioを最適化するために行われました。Neelie Kroesはフィールドデーを持っていて、EUが見つかったらもう1億ドルを持つことになるでしょう:)
他のヒント
ビルドされたほとんどの文字列はおそらく小さいので、比較的小さいバッファサイズを使用すると、メモリが多すぎない間にほとんどの操作がカバーされます。多くのスレッドが作成されている可能性があるスレッドプールがあると考えてください。キャッシュされたバッファのためにそれらのうちの1つが2kbになると、それはある程度のメモリに加算されます。
所属していません StackOverflow