Java中嵌套方法调用的成本

3

我认为,通过编译器优化(例如内联),一个方法是否嵌套几层实际上并没有太大的区别。这确实是事实吗?

例如,假设声明了以下3个类:

public class Third extends Second
{
    public int test3() // Call test2() and nothing else
    {
        return super.test2();
    }
}

public class Second extends First
{
    public int test2()
    {
        return super.test1(); // Call test1() and nothing else
    }
}

public class First
{
    public int test1() // Calculate a result somehow
    {
        int result = 0;
        ...
        return result;
    }
}

已经有三个实例化的对象thirdsecondfirst,以下调用的成本基本相同吗?

third.test3();
third.test2();
third.test1();
second.test2();
second.test1();
first.test1();

如果方法名称相同,对优化有影响吗?


为什么不自己测量一下呢? - OscarRyz
在一个简单的程序中,没有可靠的方法来测量这个问题,因此我正在寻找关于Java编译器优化(Hotspot等)的答案。 - PNS
2个回答

4

你需要担心方法调用开销吗?大多数情况下,不需要。只有当你有一个在循环中被频繁调用的方法时,这种开销才会有影响。

通常,纳秒级的时间差别并不重要,当你的方法所做的工作将成为执行过程中完整的时间开销时。此外,正如你提到的,Java HotSpot VM确实会在适当的情况下对方法调用进行内联。然而,这个决定由VM来做。请参见此链接:

http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html

现在的软件开发有更重要的事情需要关注,快发布应用吧!


1
+1,赞同指出这只在循环中才有意义。 - user949300
事实上,通常你不知道你的方法将如何被使用(比如像日志记录API这样的东西)。这就是为什么我来到这篇文章,并很高兴得知HotSpot优化了这种情况。 - zakmck

3

每个嵌套调用都会占用调用堆栈上的另一个位置。由于在方法中不做太多其他事情,这将构成调用方法的主要“成本”,因此这将产生影响。

对用户来说完全无法察觉,但仍然存在差异。


当然可以,但是编译器可能会进行优化(例如内联),因此这可能并不必要。 - PNS
如果HotSpot可以内联甚至非final调用,那么它肯定可以内联super构造函数调用,因为构造函数是静态调用的,没有覆盖可能性。当然,如果您关心早期性能,最初会有3个单独的帧... - Daniel Lubarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接