4

我有一个用于添加向量的函数,如下所示:

public static Vector AddVector(Vector v1, Vector v2)
{
    return new Vector(
      v1.X + v2.X,
      v1.Y + v2.Y,
      v1.Z + v2.Z);
}

不是很有趣。但是,我为向量重载了“+”运算符,并在重载中调用了 AddVector 函数以避免代码重复。我很好奇这是否会导致两个方法调用,或者是否会在编译或 JIT 时进行优化。我发现它确实导致了两次方法调用,因为我总共获得了 10 %通过复制 AddVector 的代码以及 '+' 和 '*' 运算符重载方法中的点积方法来提高性能。当然,这是一个小众案例,因为它们每秒被调用数万次,但我没想到会这样。我想我希望该方法被内联到另一个或其他东西中。而且我认为这不仅仅是方法调用的开销,还有将方法参数复制到另一个方法(它们是结构)中。

没什么大不了的,我可以复制代码(或者可能只是删除 AddVector 方法,因为我从不直接调用它)但是当我决定为某事创建一个方法时,它会在未来困扰我很多,比如拆分一个大方法分成几个小方法。

4

6 回答 6

5

如果您编译到调试模式或使用附加的调试器开始该过程(尽管您可以稍后添加一个),那么包括内联在内的一大类 JIT 优化将不会发生。

尝试通过在发布模式下编译它来重新运行您的测试,然后在没有附加调试器的情况下运行它(在 VS 中为 Ctrl+F5),看看您是否看到了预期的优化。

于 2009-02-02T19:07:30.437 回答
3

“而且我认为这不仅仅是方法调用的开销,还有将方法参数复制到另一个方法(它们是结构)中。”

你为什么不测试一下?编写一个引用两个向量结构而不是结构本身的 AddVector 版本。

于 2009-02-02T19:02:53.067 回答
1

不要认为这struct是性能的正确选择。在某些情况下,复制成本可能很高。直到你测量你才知道。此外,structs 具有令人毛骨悚然的行为,特别是如果它们是可变的,但即使它们不是。

另外,其他人说的是正确的:

  • 在调试器下运行将禁用 JIT 优化,使您的性能测量无效。
  • 在调试模式下编译也会使性能测量无效。
于 2009-02-02T19:21:20.737 回答
1

我有 VS 处于发布模式,我没有调试就跑了,所以这不能怪。在 Release 文件夹中运行 .exe 会产生相同的结果。我安装了 .NET 3.5 SP1。

我是否使用结构取决于我创建了多少东西以及复制与引用时它有多大。

于 2009-02-02T20:33:50.357 回答
0

你说Vector的是一个结构。根据2004 年的一篇博文,值类型是不内联方法的一个原因。我不知道在此期间规则是否发生了变化。

于 2009-02-02T19:10:56.933 回答
0

我能想到的只有一个优化,也许你想要一个 vOut 参数,这样你就可以避免调用 new() 从而减少垃圾收集——当然,这完全取决于你对返回的向量做了什么,如果你是否需要坚持它,如果你遇到垃圾收集问题。

于 2009-02-02T21:03:23.510 回答