title: StringBuilder with Caching, ThreadStatic
body: <p>I came across the code below from <a href="https://docs.microsoft.com/en-us/dotnet/framework/performance/writing-large-responsive-apps" rel="nofollow noreferrer">Writing Large, Responsive .NET Framework Apps</a>.</p>
  
  <p>The code below creates a string like <code>SomeType&lt;T1, T2, T3&gt;</code> using <code>StringBuilder</code>, and demonstrating caching <code>StringBuilder</code> to improve performance.</p>
  
  <pre><code> public void Test3()
          {
              Console.WriteLine(GenerateFullTypeName("SomeType", 3));
          }
  
          // Constructs a name like "SomeType&lt;T1, T2, T3&gt;"  
          public string GenerateFullTypeName(string name, int arity)
          {
              //StringBuilder sb = new StringBuilder();
              StringBuilder sb = AcquireBuilder();
  
              sb.Append(name);
              if (arity != 0)
              {
                  sb.Append("&lt;");
                  for (int i = 1; i &lt; arity; i++)
                  {
                      sb.Append("T"); sb.Append(i.ToString()); sb.Append(", ");
                  }
                  sb.Append("T"); sb.Append(arity.ToString()); sb.Append("&gt;");
              }
  
              //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;
          }
  </code></pre>
  
  <p>However, is it correct that the two modified methods below are better in terms of caching StringBuilder?? Only AcquireBuilder needs to know how to cache it.</p>
  
  <pre><code> 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;
          }
  </code></pre>
  
  <p>Another issue is that the original methods are not thread-safe, why is ThreadStatic used in the demo?</p>