6

假设我有一个 Web 应用程序,我想利用新Span<T>类型来降低 GC 压力并提高性能。

我应该注意哪些模式?.NET 团队在实现此新功能时是否考虑过任何典型操作?

4

1 回答 1

3

在很多情况下,这种新的类和基础设施可以提供帮助,但它们是否常见取决于您的代码......

例如,请参阅此 C# 7.2 之前的实现:

static void Main(string[] args)
{
    byte[] file = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
    byte[] header = file.Take(4).ToArray();
    byte[] content = file.Skip(4).ToArray();

    bool isValid = IsValidHeader(header);
}

private static bool IsValidHeader(byte[] header)
{
    return header[0] == 0 && header[1] == 1;
}

file.Take(4).ToArray()和是这里的byte[] content = file.Skip(4).ToArray();问题:我们必须创建一个新数组来拆分字节数组的两个部分。当字节数组的大小变大时,你可以想象对性能和内存使用的影响(想象一个 10 MB 的file数组,突然占用 20 MB 的内存)。

现在查看 C# 7.2 实现:

static void Main(string[] args)
{
    byte[] file = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
    var header = file.Take(4);
    var content = file.Skip(4);

    bool isValid = IsValidHeader(header);
}

private static bool IsValidHeader(ReadOnlySpan<byte> header)
{
    return header[0] == 0 && header[1] == 1;
}

在此处使用ReadOnlySpan<T>Span<T>基础设施的一部分)可以使用数组中的数据,而无需复制它!内存压力还是10MB。数组不重复。由于数组、列表和流阅读器都使用Span<T>,您可以为所有源构建一种通用方法。

当然,这也可以实现IEnumerable<T>,但是这种性能要好得多(例如,如果您content重复使用该变量,则不会无休止地跳过)。

于 2017-11-22T09:35:56.707 回答