4

http://s24.postimg.org/9y073weid/refactor_vs_non_refactor.png 在此处输入图像描述 这里是简单加法操作的重构和非重构代码执行时间的结果(以纳秒为单位)。1 到 5 是代码的连续运行。我的目的只是想知道将逻辑拆分成多个方法是否会导致执行速度变慢,这里的结果表明,是的,只是将方法放在堆栈上需要相当长的时间。

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

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

    package com.sim;

公共类 NonThreadedMethodCallBenchMark{

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);
}

}

4

2 回答 2

4

您应该考虑可以优化没有做任何有用的代码。如果您不小心,您可能会计时检测代码没有做任何有用的事情所需的时间,而不是运行代码。如果您使用多种方法,则检测无用代码可能需要更长的时间,从而产生不同的结果。在代码预热后,我总是会查看稳态性能。

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

  • 较小的方法可以更好地优化,因为复杂的方法可以击败优化技巧。
  • 较小的方法可以被消除,因为它们是内联的。

如果您从不预热代码,它可能会变慢。但是,如果很少调用代码,则不太重要(除非在低延迟系统中,在这种情况下,我建议您在启动时预热代码)

如果你跑

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");
}

印刷

************Starting***************
Total :8644835 nanoseconds
Total :3363047 nanoseconds
Total :52 nanoseconds
Total :30 nanoseconds
Total :30 nanoseconds

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

于 2013-06-23T10:05:38.070 回答
2

是的,额外的方法调用会花费额外的时间(除了编译器/抖动实际上进行内联的情况,我认为其中一些有时会这样做,但在您难以控制的情况下)。

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

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

于 2013-06-23T08:43:41.673 回答