代码优化

Code optimality

每次编写代码时,我都会在创建更多变量和使用方法之间进退两难,这使代码更清晰但不是最优的?你能告诉我什么对我们的应用程序性能更好吗?

例如:

protected static <T> void exch(List<T> list, Object o1, Object o2) {
    list.set(list.indexOf(o1), list.set(list.indexOf(o2), list.get(list.indexOf(o1))));
}

我应该使用:

indexOf(o1)

两次还是创建临时变量?

PS就是为了给你说清楚。我正在为我的大学项目编写几种类型的排序方法。我们正在对包含 ~150k 元素的列表进行排序。我真的很想得到最好的表现。

如果我正在编写该方法的详细信息,并且为了提高可读性,我可能会这样做。

protected static <T> void exch(List<T> list, Object o1, Object o2) {
    int indexOfO1 = list.indexOf(o1);
    int indexOfO2 = list.indexOf(o2);
    // TODO: Handle if either indexOf was out of range.
    list.set(indexOfO2, o1);
    list.set(indexOfO1, o2);
}

我认为就性能而言,像您那样在一行中执行此操作不会很重要。了解过早优化。

如果你交换对象,你能做的最好的确实是先计算indexOf(o1)一次,因为这是一个O(n) 操作:意味着如果你有一个包含 ~100k 元素的列表,与 最差的 ~50k 元素相比,它需要大约两倍的时间 案例。您不想两次执行这项昂贵的任务。所以你可以将它优化为:

protected static <T> void exch(List<T> list, <b>T</b> o1, <b>T</b> o2) {
    <b>int i1 = list.indexOf(o1);</b>
    list.set(<b>i1</b>, list.set(list.indexOf(o2), list.get(<b>i1</b>)));
}

但这还不是全部。您 不需要调用 list.get(i1):您知道结果将是 o1(前提是您没有覆盖 .equals(..) 方法。但是如果您正在排序,我假设你引用了 real 对象,而不是 equivalent 对象。所以你可以将它重写为:

protected static <T> void exch(List<T> list, T o1, T o2) {
    int <b>i2</b> = list.indexOf(o2);
    list.set(list.indexOf(o1),<b>o2</b>);
    list.set(<b>i2</b>,<b>o1</b>);
}

这里至关重要的是先获取o2的索引:因为有了list.set(..,o2),就有了映射到 o2 的两个索引。为了得到旧的,我们首先要获得索引。

在方法中声明 int 对垃圾收集过程没有影响int 将在 上声明调用 stack 否则它将使用累加器(因此根本没有内存地址)。这取决于您的处理器体系结构等。然而,声明 int 对速度的影响很小。单独进行方法调用会产生更大的影响:您在调用堆栈上创建一个调用框架,必须跳转到该方法等。与声明一个 int.[=25 相比,开销是 "large" =]

尽管如此,如果您通过 fetching 交换对象,我认为您的排序算法是 糟糕的设计 52=]。如前所述,这是一个 O(n) 操作。如果您对指数进行簿记。你可以使它成为一个 O(1) 操作(这将导致大约 ~50k 的加速)所以这就是真正的加速所在(即使你设法获得最大收益在 indexOf 方法中,它本质上会被处理索引的方法胜过)。然后你可以像这样实现它:

protected static <T> void exch(List<T> list, int i1, int i2) {
    <b>T o1 = list.get(i1);</b>
    list.set(i1,list.get(i2));
    list.set(i2,o1);
}