改进交叉口算法

时间:2013-03-26 09:53:59

标签: java intersection sortedlist

我有一个算法来构建两个排序列表的交集。如果我在性能测试中将它与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;
        }

有人看到任何进步吗?

由于

2 个答案:

答案 0 :(得分:1)

您的函数的输入始终是ArrayList类型的输入吗?

  • 如果是,从算法上讲,您的方法没有任何问题。我做了两处修改:
    1. 我将参数类型更改为ArrayList<Integer> list1, ArrayList<Integer> list2;
    2. 我只会拨打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() == 5000list2.size() == 5000intersection(list1, list2).size() == 3,该方法将分配4997个无用的整数。

尝试使用合理的容量(取决于方法的用途)或将其保留为默认值(即10)。

(请注意,分配大小为n(或 ArrayList的{​​{1}}数组的复杂性为 {{ 1}} 即可。)