私はWriting Large, Responsive .NET Framework Appsから下のコードを見つけました。StringBuilder with Caching、ThreadStatic
StringBuilder
を使用してSomeType<T1, T2, T3>
のような文字列を作成し、パフォーマンスを向上させるためにキャッシュStringBuilder
を実演します。
public void Test3()
{
Console.WriteLine(GenerateFullTypeName("SomeType", 3));
}
// Constructs a name like "SomeType<T1, T2, T3>"
public string GenerateFullTypeName(string name, int arity)
{
//StringBuilder sb = new StringBuilder();
StringBuilder sb = AcquireBuilder();
sb.Append(name);
if (arity != 0)
{
sb.Append("<");
for (int i = 1; i < arity; i++)
{
sb.Append("T"); sb.Append(i.ToString()); sb.Append(", ");
}
sb.Append("T"); sb.Append(arity.ToString()); sb.Append(">");
}
//return sb.ToString();
/* Use sb as before */
return GetStringAndReleaseBuilder(sb);
}
[ThreadStatic]
private static StringBuilder cachedStringBuilder;
private static StringBuilder AcquireBuilder()
{
StringBuilder result = cachedStringBuilder;
if (result == null)
{
return new StringBuilder();
}
result.Clear();
cachedStringBuilder = null;
return result;
}
private static string GetStringAndReleaseBuilder(StringBuilder sb)
{
string result = sb.ToString();
cachedStringBuilder = sb;
return result;
}
ただし、以下の2つの修正されたメソッドは、StringBuilderのキャッシュの点で優れていますか? AcquireBuilderだけがキャッシュする方法を知る必要があります。
private static StringBuilder AcquireBuilder()
{
StringBuilder result = cachedStringBuilder;
if (result == null)
{
//unlike the method above, assign it to the cache
cachedStringBuilder = result = new StringBuilder();
return result;
}
result.Clear();
//no need to null it
// cachedStringBuilder = null;
return result;
}
private static string GetStringAndReleaseBuilder(StringBuilder sb)
{
string result = sb.ToString();
//other method does not to assign it again.
//cachedStringBuilder = sb;
return result;
}
もう1つの問題は、元のメソッドはスレッドセーフではないということです。なぜなら、ThreadStaticはデモで使用されているのですか?
「AcquireBuilder」のさらに優れた実装です:['ObjectPool .Get'](https://docs.microsoft.com/aspnet/core/api/microsoft.extensions.objectpool.objectpool-1) 。それはASP.NET自体が使用するものです。私はなぜ作者が何かオリジナルのものを考え出す必要があると感じたのか分かりません。 –
これは既に[フレームワークに組み込まれています(https://stackoverflow.com/questions/20029868/understanding-of-net-internal-stringbuildercache-class-configuration)。見た目はかなり似ています。期限切れポリシーのないキャッシュはメモリリークであることを覚えておいてください。 –