StringPool

StringPool 类型为 string 实例实现可配置池。 这可用于最大程度地减少从 charbyte 值的缓冲区创建多个 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> 值。 这同样可以大大减少分配的数量,具体取决于特定的用例场景。

示例

可以在单元测试中查找更多示例。