C# 将值参数委托给接受ref参数的函数

C# 将值参数委托给接受ref参数的函数,c#,struct,ref,C#,Struct,Ref,为了减少我正在开发的库中的维护,我尝试将类似的功能委托给单个函数。例如,假设一个有两个分量的向量,其中Add函数由ref args接受,其他函数由value args接受。其思想是简单地在by value函数中调用by ref函数,这样就只需要维护by ref函数 i、 e 问题是by-ref重载函数没有内联,这导致了我认为较慢的代码(不包括nops) 在启用JIT优化的情况下发布输出: 地址1: 地址2: 有没有办法让Add调用内联 请注意,该库需要.NET 4.0,这意味着无法使用积极的内联

为了减少我正在开发的库中的维护,我尝试将类似的功能委托给单个函数。例如,假设一个有两个分量的向量,其中Add函数由ref args接受,其他函数由value args接受。其思想是简单地在by value函数中调用by ref函数,这样就只需要维护by ref函数

i、 e

问题是by-ref重载函数没有内联,这导致了我认为较慢的代码(不包括nops)

在启用JIT优化的情况下发布输出:

地址1:

地址2:

有没有办法让Add调用内联

请注意,该库需要.NET 4.0,这意味着无法使用积极的内联功能。

请尝试启用:

它提示编译器(或JIT'er)内联该函数


注:<代码>攻击内衬<代码>是.NET 4.5中的新版本。

< p>我将大胆猜测,并说您可能是一个C++程序员。这里使用的
ref
out
关键字完全是多余的。您可以删除它们,代码将正常运行

事实上,我看不到任何简单版本无法提供的功能:

public Vector2 Add(Vector2 other)
{
    return new Vector2() { X = this.X + other.X, Y = this.Y + other.Y };
}
即使您希望保持API静态,也要删除所有
ref
out
关键字,它们对于您的代码来说不是必需的

编辑:

我刚刚注意到你使用的是结构(值类型),所以我之前写的不正确,所以我删除了我的帖子。然后我又想了想:要么你想让它成为一个值类型,因为它太小了,复制速度足够快,要么你不想。您将其设置为一种值类型,现在您正试图通过误用
ref
out
关键字来绕过您自己的决定

public static void Add(ref Vector2 a, ref Vector2 b, out Vector2 result)
这可能很容易实现

public static void Add(Vector2 a, Vector2 b, ref Vector2 result)

如果您想通过引用传递,为什么不首先将其设置为引用类型?如果你这样做了,那么我上面写的所有东西仍然是有效的:)

我将咬紧牙关,手动内联代码,内联不是自动完成的,调用指令将是重要的,比如在像Add1这样的函数中。在这种情况下,自动化单元测试可以处理问题检测,因此维护噩梦并不是一个大问题


感谢SO的帮助。

这是SO的第一次(可能还有很多老用户),这是一篇研究得很好的帖子!很高兴有你在这里-Patrick谢谢,但实际上我不是第一次使用(我早就忘了我的原始帐户详细信息)-DMAN攻击性内联在4.0中不可用,这是当前的最低要求。请在问题中提及此要求,以防止误解。删除了我的标志。注意:
aggressiveInline
是.Net4.5中的新代码。该代码在物理处理中大量使用,在可能的情况下通过ref语义传递时会大大加快速度(注意,还有Vector3/Vector4/更大的结构不适合单个机器字)。by value重载在没有副本的情况下是不可能进行by ref传递的,例如在传递属性时。@user3446285为什么首先将其设置为值类型?在应用程序的其他位置使用结构是否更快?库的主要目标之一是减少频繁的堆分配,从而减少垃圾和随后的收集周期。结构非常有帮助。@user3613916的确:)大型对象不应该是值类型的想法源于这样一种观念,即对象通常是按值传递的。当可以避免语义上不必要的复制时,大型公开字段值类型的数组比可变类类型的数组提供更好的缓存局部性。
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Add(ref Vector2 a, ref Vector2 b, out Vector2 result)
{
    result.X = a.X + b.X;
    result.Y = a.Y + b.Y;
}
public Vector2 Add(Vector2 other)
{
    return new Vector2() { X = this.X + other.X, Y = this.Y + other.Y };
}
public static void Add(ref Vector2 a, ref Vector2 b, out Vector2 result)
public static void Add(Vector2 a, Vector2 b, ref Vector2 result)