StringPool 类型为 string 实例实现可配置池。 这可用于最大程度地减少从 char 或 byte 值的缓冲区创建多个 string 实例时执行的分配。 它提供一种有点类似于 string 集中的机制,主要区别在于池可配置、可重置,使用尽力而为策略实现,并且不需要预先实例化 string 对象,因此也可在处理临时缓冲区时保存初始分配。
平台 API: StringPool
语法
StringPool 的主要入口点是其 GetOrAdd(ReadOnlySpan<char>) API,它返回一个与输入 ReadOnlySpan<char> 的内容匹配的 string 实例,有可能从内部池中获取返回的对象。
例如,假设我们有一个输入 string,表示给定 Web 请求的 URL,并且我们还希望检索仅包含主机名的 string。 如果收到大量可能针对少数主机的请求,我们可能需要缓存这些 string 实例,此时可以使用如下所示的 StringPool 类型来执行此类操作:
public static string GetHost(string url)
{
// We assume the input might start either with eg. https:// (or other prefix),
// or directly with the host name. Furthermore, we also assume that the input
// URL will always have a '/' character right after the host name.
// For instance: "https://learn.microsoft.com/dotnet/api/system.string.intern".
int
prefixOffset = url.AsSpan().IndexOf(stackalloc char[] { ':', '/', '/' }),
startIndex = prefixOffset == -1 ? 0 : prefixOffset + 3,
endIndex = url.AsSpan(startIndex).IndexOf('/');
// In this example, it would be "learn.microsoft.com"
ReadOnlySpan<char> span = url.AsSpan(startIndex, endIndex);
return StringPool.Shared.GetOrAdd(span);
}
如果请求的 string 在缓存中已存在,则上述方法不会进行任何分配,因为查找只使用表示输入 URL string 上视图的 ReadOnlySpan<char> 输入来完成。
使用其他编码(例如 UTF8)分析原始请求时,StringPool 类型也很有用。 有一个采用输入 ReadOnlySpan<byte> 和 Encoding 实例的 GetOrAdd 重载,它使用从池租用的临时缓冲区来检索要用于查找的 ReadOnlySpan<char> 值。 这同样可以大大减少分配的数量,具体取决于特定的用例场景。
示例
可以在单元测试中查找更多示例。