请问有没有比我目前使用的笛卡尔积算法更高效的演示(如果有的话)?我已经在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 .
我们仍然需要进行一个笛卡尔积来获取最终结果,因为第二个和第三个模式仍然是不相交的,但通过重新排序我们限制了第二个模式结果的大小,这意味着我们的笛卡尔积的大小将会小得多。还有一些其他的优化,但我不会在这里发布它们,因为这涉及到 SPARQL 引擎内部的相当详细的讨论。如果有人对进一步的细节感兴趣,请留言或发送推文@RobVesse。