Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs b/src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs
new file mode 100644
index 000000000..e699cc27c
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Text/StringBuilderCache.cs
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Text
+{
+ /// <summary>Provide a cached reusable instance of stringbuilder per thread.</summary>
+ internal static class StringBuilderCache
+ {
+ // 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 MaxBuilderSize = 360;
+ private const int DefaultCapacity = 16; // == StringBuilder.DefaultCapacity
+
+ // WARNING: We allow diagnostic tools to directly inspect this member (t_cachedInstance).
+ // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
+ // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
+ // Get in touch with the diagnostics team if you have questions.
+ [ThreadStatic]
+ private static StringBuilder t_cachedInstance;
+
+ /// <summary>Get a StringBuilder for the specified capacity.</summary>
+ /// <remarks>If a StringBuilder of an appropriate size is cached, it will be returned and the cache emptied.</remarks>
+ public static StringBuilder Acquire(int capacity = DefaultCapacity)
+ {
+ if (capacity <= MaxBuilderSize)
+ {
+ StringBuilder sb = t_cachedInstance;
+ if (sb != null)
+ {
+ // Avoid stringbuilder block fragmentation by getting a new StringBuilder
+ // when the requested size is larger than the current capacity
+ if (capacity <= sb.Capacity)
+ {
+ t_cachedInstance = null;
+ sb.Clear();
+ return sb;
+ }
+ }
+ }
+ return new StringBuilder(capacity);
+ }
+
+ /// <summary>Place the specified builder in the cache if it is not too big.</summary>
+ public static void Release(StringBuilder sb)
+ {
+ if (sb.Capacity <= MaxBuilderSize)
+ {
+ t_cachedInstance = sb;
+ }
+ }
+
+ /// <summary>ToString() the stringbuilder, Release it to the cache, and return the resulting string.</summary>
+ public static string GetStringAndRelease(StringBuilder sb)
+ {
+ string result = sb.ToString();
+ Release(sb);
+ return result;
+ }
+ }
+}