【问题标题】:c# multiplication operator that takes operands by referencec#乘法运算符,通过引用获取操作数
【发布时间】:2017-09-07 03:03:30
【问题描述】:

我在数学库中有 struct 类型的 4x4 矩阵。它们应该保持结构(否则堆分配过多,垃圾过多)。

有一个乘法运算符:

public static Matrix4d operator *(Matrix4d lhs, Matrix4d rhs) {...}

并且有一个成员函数通过 ref 获取右手矩阵:

public Matrix4d Mult(ref Matrix4d rhs) {...}

现在写

Matrix4d DfromA = DfromC * CfromB * BfromA;

比写作更易读

Matrix4d DfromB = DfromC.Mult(ref CfromB);
Matrix4d DfromA = DfromB.Mult(ref BfromA);

不幸的是,第二个版本的速度是原来的两倍。

问题:

  1. 为什么编译器不够聪明,无法通过引用隐式地将参数传递给 * 运算符?或者当 sizeof() 大于某个阈值时,一般通过引用来处理方法的值类型参数?

  2. 有什么方法可以让第二个选项的性能与第一个选项的可读性相同?

【问题讨论】:

    标签: c# matrix reference operators


    【解决方案1】:

    没有,C# 语言中还没有内置任何内容。

    github上有一个关于“只读”参数的提议:

    #115: 建议:本地和参数的“只读”

    但是,这并没有(据我所知)正式添加到路线图中,也没有明确说明这对运营商来说是可能的(尽管我怀疑它会)。

    但现在,不,没有办法使用第一个解决方案的语法获得第二个解决方案的 ref-ness。

    如果您对不安全代码感到满意,您可以在某种程度上通过将运算符的参数之一设为地址来获得一些的行为,但其中一个操作符必须是结构体本身,它会通过内存复制提供,所以并不全是好的。

    这里的代码只是为了完整性但我强烈建议不要这样做!

    public static Matrix4d operator *(Matrix4d a, Matrix4d* b)
    {
        return new Matrix4d(a.V00 * (*b).V00, ...);
    }
    

    你必须这样称呼它:

    Matrix4d c = a * &b;
    

    【讨论】:

      猜你喜欢
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 2016-10-29
      相关资源
      最近更新 更多