[英]Understanding of .NET internal StringBuilderCache class configuration
When I was looking at decompiled .NET assemblies to see some internals, I've noticed interesting StringBuilderCache
class used by multiple framework's methods:当我查看反编译的 .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;
}
}
Example usage we can find for example in string.Format
method:我们可以在
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);
}
While it is quite clever and for sure I will remember about such caching pattern, I wonder why MAX_BUILDER_SIZE
is so small?虽然它非常聪明,而且我肯定会记得这种缓存模式,但我想知道为什么
MAX_BUILDER_SIZE
这么小? Setting it to, let's set 2kB, wouldn't be better?设置为,让我们设置2kB,会不会更好? It would prevent from creating bigger
StringBuilder
instances with a quite little memory overhead.它会阻止以很少的内存开销创建更大的
StringBuilder
实例。
It is a per-thread cache so a low number is expected.它是一个每线程缓存,因此预计数量较少。 Best to use the Reference Source for questions like this, you'll see the comments as well, which looks like (edited to fit):
最好将参考源用于此类问题,您也会看到评论, 看起来像(已编辑以适合):
// 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 designers" is a wee bit puzzling. “VS设计师”有点令人费解。 Well, not really, surely this work was done to optimize Visual Studio.
好吧,并不是真的,这项工作肯定是为了优化 Visual Studio。 Neelie Kroes would have a field day and the EU would have another billion dollars if she would find out :)
Neelie Kroes 将有一个实地考察日,如果她发现,欧盟将再有 10 亿美元:)
Most strings built are probably small, so using a relatively small buffer size will cover most of the operations while not using up too much memory.构建的大多数字符串可能很小,因此使用相对较小的缓冲区大小将覆盖大部分操作,同时不会占用太多内存。 Consider that there is a thread pool with possibly many threads being created.
考虑有一个线程池,其中可能创建了许多线程。 If every one of them would take up to 2kB for a cached buffer, it would add up to some amount of memory.
如果它们中的每一个都需要多达 2kB 的缓存缓冲区,那么它会增加一定数量的内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.