假设我有一个 Web 应用程序,我想利用新Span<T>
类型来降低 GC 压力并提高性能。
我应该注意哪些模式?.NET 团队在实现此新功能时是否考虑过任何典型操作?
假设我有一个 Web 应用程序,我想利用新Span<T>
类型来降低 GC 压力并提高性能。
我应该注意哪些模式?.NET 团队在实现此新功能时是否考虑过任何典型操作?
在很多情况下,这种新的类和基础设施可以提供帮助,但它们是否常见取决于您的代码......
例如,请参阅此 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
重复使用该变量,则不会无休止地跳过)。