2

假设我有两个重载方法,void foo(int arg)并且void foo(int[] args). 两者都对整数参数进行相同的处理。现在,我以这种方式实现了它们

void foo(int arg){
    // Some processing.
}

void foo(int[] args){
    for(int i : args)
        //The same processing as above.
}

现在,我知道避免代码重复是一个更好的设计原则,所以第二种方法也可以实现为:

void foo(int[] args){
    for(int i : args)
        foo(i);
}

但是,由于我在内部多次调用该方法,并且由于方法调用会增加开销,因此这种方法会使其变慢。所以,我的问题是:我应该使用哪种方法?

4

3 回答 3

11

你在谈论一个非常微不足道的开销。我有一个小程序可以帮助您了解它的重要性:

class Bar {
    void foo(double d) {        
        double y = (d + 1) * d / 7.1 % 31.3 + 13.12 * 20.002;
    }

    void foo1(double[] args) {
        for (double d : args) {
            foo(d);
        }
    }

    void foo2(double[] args) {
        for (double d : args) {
            double y = (d + 1) * d / 7.1 % 31.3 + 13.12 * 20.002;
        }
    }
}

这是一个测试和样品运行

   public class Main {
        public static void test(int n) {
            System.out.print(n + ",");

            double is[] = new double[n];
            for (int i = 0; i < is.length; i++) {
                is[i] = i * 1.3;
            }

            Bar bar = new Bar();
            long span;

            long start = System.currentTimeMillis();
            bar.foo1(is);
            span = System.currentTimeMillis() - start;
            System.out.print(span + ",");

            start = System.currentTimeMillis();
            bar.foo2(is);
            span = System.currentTimeMillis() - start;
            System.out.print(span + "\n");
        }

        public static void main(String[] args) {
            test(10000000);
            test(20000000);
            test(30000000);
            test(40000000);
            test(50000000);
            test(60000000);
        }
    }

这是一个输出:

10000000,389,383
20000000,743,766
30000000,1130,1113
40000000,1497,1474
50000000,1866,1853
60000000,2243,2239

foo 方法越复杂,差异就越小。所以恕我直言,忘记性能,考虑可维护性。

于 2013-09-29T05:03:46.950 回答
1

我知道这只是一个有代表性的例子,但你在这里谈论的是一个非常小的开销。一般来说,我认为首先设计代码可维护性和第二性能是标准做法。我什至会说,除非您的代码库中存在您需要解决的特定性能问题(如强大的性能测试套件所示),否则不应考虑性能优化。

如果您真的那么关心性能优化,那么无论如何您都不会用 Java 编写......

于 2013-09-29T04:39:09.753 回答
1

完全摆脱第一个,并将第二个更改为:

void foo(int...args)

具有相同的代码体。然后你不会有重复或额外的方法调用,只有循环控制开销,这不会杀死你。

于 2013-09-29T05:09:07.880 回答