我有一个算法来构建两个排序列表的交集。如果我在性能测试中将它与java.util.BitSet进行比较,我的算法很慢。
public static List<Integer> intersection(List<Integer> list1, List<Integer> list2) {
int size1 = list1.size(), size2 = list2.size();
int capacity = size1 < size2 ? size1 : size2;
List<Integer> intersection = new ArrayList<Integer>(capacity);
int i1 = 0, i2 = 0;
while (i1 < size1 && i2 < size2) {
if (list1.get(i1) < list2.get(i2))
i1++;
else if (list2.get(i2) < list1.get(i1))
i2++;
else {
intersection.add(list2.get(i2++));
i1++;
}
}
return intersection;
}
有人看到任何进步吗?
由于
答案 0 :(得分:1)
您的函数的输入始终是ArrayList
类型的输入吗?
ArrayList<Integer> list1, ArrayList<Integer> list2
; list1.get(i1)
和list2.get(i2)
一次。这可能会也可能不会对表现产生任何影响,但在风格上我更愿意将其考虑在内。get(index)
可能非常昂贵。最后,在测试效果时,请务必遵循How do I write a correct micro-benchmark in Java?
中给出的建议答案 1 :(得分:0)
你应该知道这个:
List<Integer> intersection = new ArrayList<Integer>(capacity);
分配一个大小为capacity
的内部数组。
假设list1.size() == 5000
,list2.size() == 5000
和intersection(list1, list2).size() == 3
,该方法将分配4997个无用的整数。
尝试使用合理的容量(取决于方法的用途)或将其保留为默认值(即10)。
(请注意,分配大小为n
(或 ArrayList
的{{1}}数组的复杂性为 {{ 1}} 即可。)