【问题标题】:Efficient way to equiJoin Collections of objectsequiJoin 对象集合的有效方法
【发布时间】:2021-02-20 12:59:49
【问题描述】:

假设我们有 2 个集合(适合内存),其中包含可以测试相等性的元素(不一定覆盖 equals()),例如

Collection<Integer> c1 = List.of(1,2,3,4,5);
Collection<Integer> c2 = List.of(0,2,3,5,9);

还有一些非并行方法equiJoin(c1, c2),它为您提供两个列表中相等((2,2), (3,3), (5,5)) 的元素的Collection&lt;Tuple&lt;Integer, Integer&gt;&gt;。请参阅this 以了解其在 RDBMS 上下文中的处理。创建一对相等的整数是非常无用的,但是想想任何需要匹配记录列表的情况,比如一个来自 db 和一个来自 Web 服务调用,就像在this post 中一样。让我们假设,相等性归结为简单的类型,并且本身不会产生很多复杂性。

relational databases 区域的连接已被咬死,但在一般编程中并没有看起来那么严重。

我们经常看到的(如here)是嵌套循环方法,它的运行时间复杂度不是很好,O(M*N)。我只知道一个 framework 在 Java 流中包含 equiJoin,但它 looks like 它也执行嵌套循环(它实际上允许任意函数,而不仅仅是相等,这是嵌套循环的原因)。

    List<Tuple<Integer, Integer>> joined = new ArrayList<>();
    for (Integer i : c1) {
        for (Integer j : c2) {
            if (i.equals(j)) {
                joined.add(new Tuple<>(i, j));
            }
        }
    }

如果你想做得更好,你可以使用更好的散列连接 O(M+N)

    List<Tuple<Integer, Integer>> joined = new ArrayList<>();

    HashMap<Integer, Integer> C1 = new HashMap<>();
    // imagine its not Integer but e.g. bank accounts and a Map<Key, Account>
    c1.forEach(i -> C1.put(i, i));

    for (Integer i : c2) {
        Integer j = C1.get(i);
        if (j != null) {
            joined.add(new Tuple<>(i, j));
        }
    }

问题中是否有我没有看到的可用于改进的方面,或者是否存在可以做得更好的现有算法/实现?就像一些奇异的二进制编码或匹配时搜索空间的减少,诸如此类的事情。我能想到的一切都不是很有希望,或者可能会引入比它消除的更多的工作。也许甚至有共识或证据表明您不能比哈希联接做得更好,那么这也是一个答案。

【问题讨论】:

  • 如果您询问理论,正如您所指出的,它已经在 DB 上下文中广泛完成,因此磁盘和内存操作的算法都非常完善(并且取决于在更大的体系结构上,例如数据的存储方式和索引方式)。对于实际应用,你可以看看 Kafka 是如何做到的,例如joins
  • 是的,在没有存储/io 负担的情况下看到的问题。 Kafka 不是流式应用程序吗?那是一个不同的问题。但仍然很好,也许我也会在 apache Spark 中挖掘。
  • 您基于哈希的解决方案肯定假设您在int 上进行比较。两个相互比较的项目可能在任意字段上进行比较,它们本身执行任意复杂的比较。我认为在一般情况下,你不能做得比排序更好。那么问题就变成了 - 您可以利用的一般情况有哪些限制?
  • 对于任何比较排序,排序都必须包含 nlgn 复杂度。如果您可以分类排序,那么您将回到整数建议。

标签: java algorithm collections inner-join


【解决方案1】:

看起来在这种情况下,哈希连接在看到thisthisthisthisthisthis 和 OP 的 cmets 之后无法被击败。但它可以匹配,sort-merge-join(需要可比较的对象,而不仅仅是相等或不相等)具有相同的运行时复杂度,但它无法击败哈希连接实现的简单性。

仍然可以tweak the Hashmap 这样,进入并行算法并考虑硬件相关方面(请参阅参考资料here)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多