每次我编码时,我都会在创建更多变量和使用方法之间陷入困境,这会使代码更清晰但不太理想?你能告诉我什么对我们的应用程序性能更好吗?
例如:
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元素的列表进行排序。我真的希望得到最好的表现。
答案 0 :(得分:4)
如果你在对象上交换,你可以做的最好的事情就是首先计算indexOf(o1)
一次,因为这是一个 O(n)操作:意味着如果你有一个包含~100k元素的列表,那么与最差情况下的~50k元素相比,它将需要大约两倍的时间。你不想两次做这个昂贵的任务。所以你可以优化它:
protected static <T> void exch(List<T> list, T o1, T o2) {
int i1 = list.indexOf(o1);
list.set(i1, list.set(list.indexOf(o2), list.get(i1)));
}
然而,那不是全部。您无需致电list.get(i1)
:您知道结果将是o1
(假设您未覆盖.equals(..)
方法。但如果您要排序,我假设您引用了 real 对象,而不是等效对象。所以您可以将其重写为:
protected static <T> void exch(List<T> list, T o1, T o2) {
int i2 = list.indexOf(o2);
list.set(list.indexOf(o1),o2);
list.set(i2,o1);
}
此处首先获得o2
的索引至关重要:因为一旦有list.set(..,o2)
,就会有两个索引映射到{{ 1}} 即可。为了获得旧的,我们首先获得索引。
在方法中声明o2
对垃圾收集过程没有影响:int
将在调用堆栈上声明或它将使用累加器(因此根本没有内存地址)。这取决于您的处理器架构等。然而,声明int
的影响在速度方面是最小的。单独进行方法调用会产生更大的影响:在调用堆栈上创建一个调用框架,必须跳转到该方法,等等。开销是&#34;大&#34;与宣布一个int
相比。
然而,如果您通过 获取那里的索引交换对象,我认为您的排序算法是设计不良。如前所述,这是 O(n)操作。如果您对指数进行簿记。你可以使它成为一个 O(1)操作(这将导致大约50k的加速),这就是真正的加速所在(即使你设法充分利用{ {1}}方法,它本身将通过一个处理索引的方法来胜过。然后,您可以像下面这样实现它:
int
答案 1 :(得分:1)
如果我正在编写该方法的详细信息,我可能会这样做,如果我是为了可读性。
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);
}
我不认为像你一样在一行中这样做会在性能方面起作用。阅读有关过早优化的信息。