有人可以向我证明比目前使用的笛卡儿乘积算法更有效(假设有一个)。我已经看了周围的SO和谷歌,但看不到任何明显的东西,所以我可能会缺少一些东西。
foreach (int i in is) {
foreach (int j in js) {
//Pair i and j
}
}
这是我在代码中做的非常简化的版本。两个整数是用于检索一个/多个对象的查找键,并且来自两个查找的所有对象都被配对在一起成为新对象。
这个小型的代码块在一个更大的更复杂的系统中成为主要的性能瓶颈,因为它在规模上运行的数据集。其中一些可能通过改进用于存储对象的数据结构和所涉及的查找来缓解,但是我觉得仍然是笛卡尔乘积本身的计算的主要问题。
编辑
所以有更多的背景我的具体使用的算法,看看是否可能有任何技巧,我可以用来回应Marc的评论。整个系统是一个SPARQL查询引擎,它通过图形数据集来处理SPARQL查询,SPARQL是一种基于模式的语言,因此每个查询由一系列与图形匹配的模式组成。在两个后续模式没有共同变量(它们不相交)的情况下,有必要计算由两个模式产生的解的笛卡尔积,以获得用于整体查询的可能解的集合。可能有任何数量的模式,我可能需要多次计算笛卡尔乘积,如果查询由一系列不相交的模式组成,这可能导致可能的解决方案中相当指数的扩展。
不知怎的,从现有的答案我怀疑是否有任何技巧可以应用
更新
所以我以为我会发布一个更新我实现了为了最小化笛卡尔积分产品的需要,从而优化查询引擎一般。注意,并不总是可以完全消除对产品的需求,但是几乎总是可以进行优化,所以连接的两个组件的尺寸要小得多。
由于作为一组三重模式的每个BGP(基本图形模式)被执行为块(本质上),引擎可以自由地重新排序BGP内的模式以获得最佳性能。例如考虑以下BGP:
?a :someProperty ?b .
?c :anotherProperty ?d .
?b a :Class .
执行查询需要笛卡尔乘积,因为第一种模式的结果与第二种模式不相交,因此前两种模式的结果是其各自结果的笛卡尔乘积。这个结果将包含比我们实际需要的结果更多的结果,因为第三种模式限制了第一种模式的可能结果,但是我们以后不再应用此限制。但是如果我们重新排序如下:
?b a :Class .
?a :someProperty ?b .
?c :anotherProperty ?d .
我们仍然需要一个笛卡尔乘积来获得最终的结果,因为第2和第3种模式仍然不相交,但是通过重新排序,我们限制了第二种模式的结果的大小,这意味着我们的笛卡尔积的尺寸会小得多。
我们有一些其他的优化,但是我不会在这里发布,因为它开始对SPARQL引擎内部部分进行了详细的讨论。如果有任何人对进一步的细节感兴趣,请发表评论或给我发送tweet @RobVesse