在java中将逻辑拆分为多个方法是否会降低执行速度?如果是,那么我们应该避免代码的重新分解吗

在java中将逻辑拆分为多个方法是否会降低执行速度?如果是,那么我们应该避免代码的重新分解吗,java,performance,refactoring,Java,Performance,Refactoring,这是一个简单加法操作的重分解和非重分解代码的执行时间结果,单位为纳秒。1到5是代码的连续运行。 我的目的只是想弄清楚,将逻辑拆分为多个方法是否会导致执行速度变慢,下面的结果表明,是的,将这些方法放到堆栈上需要相当长的时间 如果我做错了什么,我邀请以前做过一些研究或者想在这方面进行调查的人来纠正我,并从中得出一些结论性的结果。 在我看来,是的,代码重分解确实有助于使代码更加结构化和易于理解,但在实时游戏引擎这样的时间关键型系统中,我宁愿不要重分解 以下是我使用的简单代码: package

这是一个简单加法操作的重分解和非重分解代码的执行时间结果,单位为纳秒。1到5是代码的连续运行。 我的目的只是想弄清楚,将逻辑拆分为多个方法是否会导致执行速度变慢,下面的结果表明,是的,将这些方法放到堆栈上需要相当长的时间

如果我做错了什么,我邀请以前做过一些研究或者想在这方面进行调查的人来纠正我,并从中得出一些结论性的结果。 在我看来,是的,代码重分解确实有助于使代码更加结构化和易于理解,但在实时游戏引擎这样的时间关键型系统中,我宁愿不要重分解

以下是我使用的简单代码:

    package com.sim;
公共类非线程MethodCallBenchmark{

public static void main(String args[]){
    NonThreadedMethodCallBenchMark testObject = new NonThreadedMethodCallBenchMark();
    System.out.println("************Starting***************");
    long startTime =System.nanoTime();

    for(int i=0;i<900000;i++){
        //testObject.method(1, 2); // Uncomment this line  and comment the line below to test refactor time
        //testObject.method5(1,2); // uncomment this line and comment the above line to test non refactor time
    }
    long endTime =System.nanoTime();
    System.out.println("Total :" +(endTime-startTime)+" nanoseconds");
}

public int method(int a , int b){
    return method1(a,b);
}
public int method1(int a, int b){
    return method2(a,b);
}
public int method2(int a, int b){
    return method3(a,b);
}
public int method3(int a, int b){
    return method4(a,b);
}
public int method4(int a, int b){
    return method5(a,b);
}
public int method5(int a, int b){
    return a+b;
}
public void run() {
    int x=method(1,2);
}
publicstaticvoidmain(字符串参数[]){
NonThreadedMethodCallBenchMark testObject=新的NonThreadedMethodCallBenchMark();
System.out.println(“****************开始*******************”);
long startTime=System.nanoTime();

对于(int i=0;iYes),额外的方法调用会花费额外的时间(除了编译器/抖动实际进行内联的情况,我认为有些方法有时会进行内联,但在您会发现难以控制的情况下)

除了代码中最昂贵的部分之外,您不应该担心这一点,因为在大多数情况下,您无法看到差异。在那些性能无关紧要的情况下,您应该重构以最大限度地提高代码的清晰度


我建议您随意重构,偶尔使用探查器来测量性能,以找到昂贵的部分。只有当探查器显示某些特定代码占用了大量时间时,您才应该担心函数调用(或其他速度与清晰度的权衡)在那个特定的代码中,你会发现性能瓶颈经常出现在你猜不到的地方。

< P>你应该考虑不做任何有用的代码可以被优化。如果你不小心,你可以确定检测代码不需要什么有用的时间,而不是运行COD。e、 如果使用多种方法,检测无用的代码可能需要更长的时间,因此会产生不同的结果。我会在代码预热后查看稳态性能

对于代码中最昂贵的部分,小方法将被内联,因此它们不会对性能成本造成任何影响

  • 较小的方法可以更好地优化,因为复杂的方法可以击败优化技巧
  • 较小的方法可以消除,因为它们是内联的
如果您不预热代码,则可能会变慢。但是,如果很少调用代码,则不太重要(在低延迟系统中除外,在这种情况下,我建议您在启动时预热代码)

如果你跑

System.out.println("************Starting***************");

for (int j = 0; j < 10; j++) {
    long startTime = System.nanoTime();
    for (int i = 0; i < 1000000; i++) {
        testObject.method(1, 2);
        //testObject.method5(1,2); // uncomment this line and comment the above line to test non refactor time
    }
    long endTime = System.nanoTime();
    System.out.println("Total :" + (endTime - startTime) + " nanoseconds");
}

注意:30纳秒是执行系统所需的时间调用。内部循环和方法调用已被消除。

这是图形的链接,而不是试图从上面发布的无意义代码中得出结论,我将使用探查器查看您在实际系统中大部分时间的损失。我向您保证,这不是调用方法…您的基准测试技术nique存在严重缺陷,结果可能毫无意义。例如,请参见。至少,您应该使用微基准标记工具,如。此外,在任何更大的上下文之外测量此代码的性能是错误的。在这两种情况下,代码都会被删除,因此根本不需要花费时间。额外的时间是测试所需的时间JIT来消除代码。也就是说,OP没有测试他/她认为他们正在测试的东西。@PeterLawrey:嗯,哪个代码被消除了?你是说OP的例子中两种情况都被消除了?是的,这意味着他知道如果他测量得好,调用有时会被消除,所以这实际上是有用的。但重要的是他的代码,而不是这个例子。在那个c中例如,答案取决于他真正的代码是什么样子以及他如何测试它。
************Starting***************
Total :8644835 nanoseconds
Total :3363047 nanoseconds
Total :52 nanoseconds
Total :30 nanoseconds
Total :30 nanoseconds