具有许多参数的Java方法 - 性能

时间:2012-12-07 18:09:30

标签: java performance methods parameters

当我使用has / use方法有很多(超过一百个)参数时,在计算性能方面是否效率不高?

我并不是说在可维护性方面有效,而只是在“原始”计算性能方面:)

6 个答案:

答案 0 :(得分:3)

正如下面的文章所说,它可以用更少的参数表现更好,但它并不是一个很大的性能影响。但是你应该考虑传递一个对象。

http://www.dailyfreecode.com/forum/parameter-performance-21574.aspx

答案 1 :(得分:3)

理论上,也许,因为Java是按值传递的,这意味着当调用函数时,JVM会复制每个参数值并将副本提供给函数,因此可能存在某些点,参数数量对执行时间的影响不可忽略。但实际上,只要有可能,这些副本都是“浅层”副本,这意味着它们更像是引用,因此实际制作副本的时间非常少。因此,您可能需要超过100个参数才能对性能时间产生明显影响。

在任何情况下,即使考虑这样的事情的表现时间听起来也非常像过早的优化。它几乎肯定不是你的程序的瓶颈,所以在你确定它实际上导致减速之前,不值得花时间。如果您的程序速度慢得令人无法接受,请调查其他可能的减速来源。

当然,正如你所提到的那样,“可维护性”也是一个问题。为什么单个函数需要数百个参数?它们是复杂的参数,例如自定义对象的ArrayLists,还是简单的内置数据类型?如果是后者,为什么不考虑将它们一起打包成数组,ArrayLists等?或者,为什么不将功能分解为多个功能?现代计算机足够快,对于许多(可以说是大多数)目的而言,程序员时间比处理器时间更有价值,因此在编码时,您首先关注的问题通常应该是您所写的内容是否可理解和写得好,而不是它是否是快。

(如果你确实需要它真的非常快,你应该使用C或FORTRAN。)

答案 2 :(得分:1)

那将是一个成本。所有这些参数都必须被压入堆栈。我不认为它会在计算能力方面造成麻烦,除非它处于沉重的循环中。

你是否对同事们感到生气?或者编写某种以编程方式创建的代码?

答案 3 :(得分:1)

回答你的问题:不,传递100个参数不会导致显着的性能损失。与另一个答案不同,我建议不要传递一个对象。如果这样做,代码将变得不可维护。我看过很多人都不了解的地图。相反,使用Joshua Block在Effective Java(第7章,方法签名)中推荐的最佳实践,将参数数量降低到合理的水平。

例如:将您的方法分解为多种方法。

查看类似问题的答案:

best practice for passing many arguments to method?

答案 4 :(得分:0)

我目前正在阅读名为“Java:The Good Parts”的书。它建议一般来说,传递接口是可行的方法。我建议您使用100个参数创建一个接口,并传递它而不是传递100个参数。将来会发生的事情会更清楚。

就我而言,最大的代价就是头疼。但是,如果您正在计划进行这些参数,那么通过这些参数并没有太大差异。

答案 5 :(得分:0)

很难回答,大多数人发现不止一些方法参数表明存在严重问题。

虽然有一些方面,当你考虑它时,也表明许多方法参数会对性能产生影响。每个方法参数占用堆栈上的一个槽(就像局部变量一样)。一个插槽本身基本上是免费的,但是当你调用方法怪物时,每个参数插槽也必须填充。这意味着不可避免地会有一些READ操作来为调用者获取插槽的值,并且还有一个PUSH到堆栈中获取所述值。

所以是的,每个参数都附加了一个小成本,作为第一个近似值,成本与参数个数成线性关系。

现在,当你从某个地方提取参数值时,你实际上做的工作不仅仅是传递对所述参数的引用 - 例如假设你有一个方法来计算矩形的面积并用4个参数写出: / p>

public int area(int x1, int y1, int x2, int y2) {
     return ....;
}

而不是

public class Rectangle {
    int x1, y1, x2, y2;

    public int area() {
        return ....;
    }
}

现在在第一种情况下,您需要拉4个整数并将它们推回堆栈,而要调用第二个大小写,您只需要将引用拉到矩形。当然矩形的area()方法仍然必须拉动它的成员,但是你至少保存了3个堆栈推送(有100个参数你可能可以节省更多)。

此外,一个包含100个参数的方法意味着它是一个非常大的方法,否则大多数参数无论如何都不会被使用而且只是浪费。一个大方法表明高复杂性,这可能干扰JIT生成良好代码的能力。很难证明,但一个简单的例子就是方法内联。 JIT对内联考虑的代码数量有限制,大型方法不是候选者。 在某种程度上,你可以期望JIT能够最好地处理常用的习语(显然,优化最常见的情况可以提供更多的努力),100个方法参数绝对超出了常用的范围。