繁体   English   中英

为什么代码使用较小的列表实例化哈希集?

[英]why does the code instantiate the hashset using smaller list?

我正在检查以查看org.apache.commons.collections4.ListUtils类,并注意到代码如下:

public static <e> List<e> intersection(final List<? extends E> list1, final List<? extends E> list2) {
        final List<e> result = new ArrayList<>();

        List<? extends E> smaller = list1;
        List<? extends E> larger = list2;
        if (list1.size() > list2.size()) {
            smaller = list2;
            larger = list1;
        }

        final HashSet<e> hashSet = new HashSet<>(smaller);

        for (final E e : larger) {
            if (hashSet.contains(e)) {
                result.add(e);
                hashSet.remove(e);
            }
        }
        return result;
    }

我们知道为什么他们将较小的列表转换为哈希集并循环使用较大的列表吗? 谢谢。

假设较小的列表具有M个条目,较大的列表具有N个条目,并且Set提供了对基本操作(添加,包含)的恒定时间访问。

如果我使用Big O表示法将该算法分类,则运行时将为O(M+N)和额外的内存消耗O(M)

如果将较小的列表切换为较大的列表,则有2个观察结果:

  • 额外的内存使用量将增加到O(N) ,这是不这样做的原因之一。
  • 从纸面上看,运行时不会改变,仍然是O(M+N) ,但实际上创建N个条目的集合要比对其进行迭代更重。

如果要验证这些假设,请尝试使用JMH ,它是在Java中运行微基准测试的工具。

我对此进行了不科学的基准测试, M=1000N=10000 这就是我得到的:

Benchmark               (size)  Mode  Cnt       Score      Error  Units
IntersectBench.larger    10000  avgt    5  190481.075 ± 6488.649  ns/op
IntersectBench.smaller   10000  avgt    5  125997.594 ± 1616.975  ns/op

有趣的值在Score ,这里越小越好。 IntersectBench.smaller与上述算法相同, IntersectBench.larger是对列表进行交换并删除对它们进行优化的算法。 如您所见,未优化的版本慢了50%。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM