我正在开发一个需要支持列表和数组的内部库。这是一条热门路径,因此我们正在寻求性能改进。
目前它在参数中使用
IList<T>
,因为我们需要在库中基于索引的访问,并避免为这两种类型重写它。
public int Foo<T>(IList<T> values);
一个相当免费的性能改进(测量和基准测试)是将其转换为内部跨度,我们可以通过进行一些重载来转换值并立即传递它来完成,但感觉应该有一种更干净的方法。我不太喜欢有很多存根,尤其是当它们似乎在做非常相似的事情时。
public int Foo<T>(T[] values)
=> Foo(values.AsSpan());
public int Foo<T>(List<T> values)
=> Foo(CollectionsMarshal.AsSpan(values));
private int Foo<T>(Span<T> values)
是否有任何接口/编组可用于将列表和数组转换为 Span?
你总是可以使用
IList<T>
:
public int Foo<T>(IList<T> list)
{
Span<T> span;
if (list is T[] array)
{
span = array.AsSpan();
}
else if (list is List<T> concreteList)
{
span = CollectionsMarshal.AsSpan(concreteList);
}
else
{
throw new NotSupportedException("not supported!");
}
return Foo(span);
}
private int Foo<T>(Span<T> values)
{
// ...
}