【问题标题】:Why are Span<T> extension methods not implemented with the 'in' parameter modifier?为什么 Span<T> 扩展方法没有使用 'in' 参数修饰符实现?
【发布时间】:2019-01-31 16:53:11
【问题描述】:

随着 C#7.2 的发布,出现了 in parameter modifierSpan&lt;T&gt; struct。 Span 现在已经在 .NET Core 周围泛滥 API。还发布了一个 .NET Standard API (System.Memory),可以使用 Span&lt;T&gt;ReadOnlySpan&lt;T&gt; 等。

System.Memory API 的一部分是这些切片类型as seen here 的扩展方法。

问题是,为什么这些扩展方法不使用跨度的in 参数修饰符来实现?由于Span&lt;T&gt;ReadOnlySpan&lt;T&gt;ref readonly struct 类型,这些方法似乎会导致运行时创建传递给这些方法的跨度的防御性副本。我知道这个副本相对便宜,但似乎会看到小的性能提升。

这些扩展方法的一些 .NET Core 实现是located here

为了澄清,我期待这样的方法签名:

public static int IndexOf<T>(this in System.Span<T> span, T value) where T : System.IEquatable<T>
public static System.ReadOnlySpan<char> Trim(this in System.ReadOnlySpan<char> span)
public static bool IsWhiteSpace(this in System.ReadOnlySpan<char> span)

【问题讨论】:

    标签: c# .net .net-core


    【解决方案1】:

    因为in 既有优点也有缺点;大多数优点都与结构复制性能有关,并避免不必要的大型结构副本(特别强调“大”),但Span&lt;T&gt; 不是大型结构,并且在几乎所有测试中我已经看到,在 Span&lt;T&gt; 上使用 in降低性能,或者(不太常见)对性能没有影响 - 所以即使在最好的情况下(在不降低性能的情况下),实际上没有理由添加它。

    【讨论】:

    • 您能否指出任何基准或支持性能声明的文章?
    • @omajid 不确定他们是否被写了出来——其中很多都是即时的;不过,我可以看看旧日志。我可以指出commit cmets说要在跨度上恢复in,因此提醒一下:)
    • @omajid 我在这里从内存中工作,所以不要引用我的话,但是 IIRC 的问题是三次:in 添加了取消引用,它减少了堆栈局部性(使其不太可能使用一个寄存器),并且 JIT 优化(对于核心上的 2 字段跨度,而不是框架上的 3 字段跨度)不能通过额外的间接应用。
    猜你喜欢
    • 2019-03-20
    • 2018-08-24
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    相关资源
    最近更新 更多