| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | namespace System.Text |
| | | 5 | | { |
| | | 6 | | /// <summary>Provide a cached reusable instance of stringbuilder per thread.</summary> |
| | | 7 | | internal static class StringBuilderCache |
| | | 8 | | { |
| | | 9 | | // The value 360 was chosen in discussion with performance experts as a compromise between using |
| | | 10 | | // as little memory per thread as possible and still covering a large part of short-lived |
| | | 11 | | // StringBuilder creations on the startup path of VS designers. |
| | | 12 | | internal const int MaxBuilderSize = 360; |
| | | 13 | | private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity |
| | | 14 | | |
| | | 15 | | [ThreadStatic] |
| | | 16 | | private static StringBuilder? t_cachedInstance; |
| | | 17 | | |
| | | 18 | | /// <summary>Get a StringBuilder for the specified capacity.</summary> |
| | | 19 | | /// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</re |
| | | 20 | | public static StringBuilder Acquire(int capacity = DefaultCapacity) |
| | 826406 | 21 | | { |
| | 826406 | 22 | | if (capacity <= MaxBuilderSize) |
| | 826406 | 23 | | { |
| | 826406 | 24 | | StringBuilder? sb = t_cachedInstance; |
| | 826406 | 25 | | if (sb != null) |
| | 824864 | 26 | | { |
| | | 27 | | // Avoid stringbuilder block fragmentation by getting a new StringBuilder |
| | | 28 | | // when the requested size is larger than the current capacity |
| | 824864 | 29 | | if (capacity <= sb.Capacity) |
| | 824864 | 30 | | { |
| | 824864 | 31 | | t_cachedInstance = null; |
| | 824864 | 32 | | sb.Clear(); |
| | 824864 | 33 | | return sb; |
| | | 34 | | } |
| | 0 | 35 | | } |
| | 1542 | 36 | | } |
| | | 37 | | |
| | 1542 | 38 | | return new StringBuilder(capacity); |
| | 826406 | 39 | | } |
| | | 40 | | |
| | | 41 | | /// <summary>Place the specified builder in the cache if it is not too big.</summary> |
| | | 42 | | public static void Release(StringBuilder sb) |
| | 826406 | 43 | | { |
| | 826406 | 44 | | if (sb.Capacity <= MaxBuilderSize) |
| | 824865 | 45 | | { |
| | 824865 | 46 | | t_cachedInstance = sb; |
| | 824865 | 47 | | } |
| | 826406 | 48 | | } |
| | | 49 | | |
| | | 50 | | /// <summary>ToString() the stringbuilder, Release it to the cache, and return the resulting string.</summary> |
| | | 51 | | public static string GetStringAndRelease(StringBuilder sb) |
| | 826406 | 52 | | { |
| | 826406 | 53 | | string result = sb.ToString(); |
| | 826406 | 54 | | Release(sb); |
| | 826406 | 55 | | return result; |
| | 826406 | 56 | | } |
| | | 57 | | } |
| | | 58 | | } |