【发布时间】:2016-04-25 00:04:47
【问题描述】:
如何重写这段代码以获得更好的性能?
int i = 0;
ArrayList<ArrayList> data = new ArrayList<ArrayList>();
//---- fill data with 2 equally large ArrayLists, 2 table columns here
for (int n = 0; n < data.get(0).size(); n++) { //Loop for whole table
if (i < n){ //not to enter second loop, while in previous second loop
if (data.get(1).get(n) > 0){ // row with condition when to enter second loop
for (i = n; i < data.get(0).size(); i++){ //second loop
if (data.get(0).get(i) > data.get(0).get(n) + 10 ){ // breaks second loop
//somecode
break;
}
}
}
}
}
基本上是做什么的,它逐行遍历表(第一个循环),直到找到第一个特定的“开始”行(第二列> 0),从这一点开始它寻找另一个特定的“结束”行(第二个循环),直到找到它(该行中的值必须至少比起始行中的值高 10)并结束第二个循环。如果它已经在一个循环中,它将不会进入第二个循环。它将仅在具有结束条件的最后一行(if (i
我知道这很粗糙,我用高中的视觉基础知识转化为java语言。
我怎样才能以更好的方式进行编程,以获得更好的性能,因为表/数组真的很长,我必须经历很多次寻找不同的起始条件(也许使用 db 而不是arraylists?,数据库查询是什么样的?)
【问题讨论】:
-
我认为 SQL 只会增加开销,因为查询的性质是动态的。 IMO 可以做的最好的事情是尝试重新编写代码或对其进行预处理以避免结构中的“扫描”。
-
不,那是我第一次想到的。基本上我想要编。做解释和按顺序做的事情,因为输入表/数据是按时间排序的。
-
列表中的数据是否按该字段排序?在这种情况下,您可以使用binary search 找到值为 0 的值,然后找到其后的值为 +10。
-
您可以正确使用泛型(例如
ArrayList<ArrayList<Integer>>),并且您有两列并且它们是匿名的这一事实无助于可读性。您可以制作两个 1D 列表,也可以使用您的一些自定义对象作为条目制作 1D 列表,这将帮助您提高您和我们的可读性。 -
至于您的问题本身:您的算法似乎具有线性复杂度,这非常好。您可能可以使代码更具可读性,但它似乎不是瓶颈,除非您的数组真的很大并且您重复执行此操作(例如,在添加一行之后)。然而这些都是我们一无所知的因素,你只描述了这个算法。