为什么不能对此进行优化?

时间:2009-02-02 18:52:30

标签: c# performance optimization methods

我有一个用来添加矢量的函数,如:

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时优化。我发现它确实导致两个方法调用,因为我通过复制AddVector的代码以及'+'和'*中的点积方法,在性能中获得了10%的成功率'运算符重载方法。当然,这是一个利基案例,因为它们被称为每秒数万次,但我没想到这一点。我想我希望这个方法可以在另一个方面内联,或者其他东西。我想这不仅仅是方法调用的开销,还包括将方法参数复制到另一个方法(它们是结构)。

这没什么大不了的,我可以复制代码(或者只是删除AddVector方法,因为我从不直接调用它)但是当我决定为某些东西创建一个方法时,它将在未来唠叨我很多将一个大方法分成几个较小的方法。

6 个答案:

答案 0 :(得分:5)

如果你编译成调试模式或者在调试器附加的情况下开始进程(虽然你可以稍后添加),那么就不会发生大量的JIT优化,包括内联。

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

答案 1 :(得分:3)

  

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

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

答案 2 :(得分:1)

不要认为struct是性能的正确选择。在某些情况下,复制成本可能很高。直到你衡量你不知道。此外,structspooky行为,特别是如果它们是可变的,但即使它们不是。

此外,其他人所说的是正确的:

  • 在调试器下运行将禁用JIT优化,使您的性能测量无效。
  • 在调试模式下编译也会使性能测量无效。

答案 3 :(得分:1)

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

我是否使用结构取决于我创建的内容的数量以及复制与引用时的大小。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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