【发布时间】:2014-01-06 19:05:18
【问题描述】:
我需要有效地找到字符串列表对的(交集大小/联合大小)的比率。这些列表很小(主要是大约 3 到 10 个项目),但我有大量的列表(~300K)并且必须在每一对上都这样做,所以我需要这个实际计算尽可能高效。字符串本身是短的 unicode 字符串——平均大约 5-10 个 unicode 字符。
Efficiently compute Intersection of two Sets in Java? 此处接受的答案看起来非常有帮助,但(可能是因为我的集合很小(?))使用接受的答案中建议的方法,我没有得到太大的改进。
这是我目前所拥有的:
protected double uuEdgeWeight(UVertex u1, UVertex u2) {
Set<String> u1Tokens = new HashSet<String>(u1.getTokenlist());
List<String> u2Tokens = u2.getTokenlist();
int intersection = 0;
int union = u1Tokens.size();
for (String s:u2Tokens) {
if (u1Tokens.contains(s)) {
intersection++;
} else {
union++;
}
}
return ((double) intersection / union);
我的问题是,鉴于我正在使用 Strings,与其他数据类型相比,检查相等性可能更耗时。
我认为因为我将多个 u2 与同一个 u1 进行比较,所以我可以通过将 u2 克隆到循环外的 HashSet 中来获得一些改进(这没有显示——这意味着我会传入HashSet 而不是我可以从中提取列表然后克隆到集合中的对象)
我还能做些什么来稍微改进一下?
提前致谢!
更新
我已经更新了上述问题的具体数字。此外,由于数据的性质,大多数(90%?)的交叉点将是空的。我最初尝试使用克隆集合,然后使用retainAll 另一个集合方法中的项目来查找交集,然后在进行克隆和addAll 之前使用快捷方式找到并集。这与上面发布的代码一样有效,大概是因为它是一个整体上较慢的算法与能够缩短很多时间之间的权衡。因此,我正在考虑如何利用重叠集的不频繁性,并希望在这方面提出任何建议。
提前致谢!
【问题讨论】:
-
这个问题似乎离题了,因为它是关于代码审查的,属于 codereview.stackexchange.com 不在这里。
-
您的列表是否有可能包含任何重复项?我也认为这不是一个代码审查,而是一个关于如何找到字符串集的快速交集和并集的有趣算法问题。
-
我想反驳的论点是这是行不通的,因为它不够快。这里和代码审查之间有一些重叠,因为他对这段代码有一个具体的问题,我认为没关系。
-
我看到这篇文章已被搁置为“离题”。如果我对其进行编辑以排除代码 sn-p 并仅询问有关如何在 Java 中最有效地执行此操作的一般性问题,是否会成为主题?我有点困惑,因为社区标准页面指出好的问题通常应该包含一些代码。他们没有说它必须是损坏的代码。我发布的代码计算了正确的函数,但它的效率不足以让我使用它,所以正如@TimB 所说,它对我的目的来说不是“工作”。
-
@JarrodRoberson 仅仅因为一个问题在其他地方是热门话题并不意味着它在这里是题外话。特别是,仅仅因为一个问题询问如何改进工作代码并不意味着它在 StackOverflow 上是题外话。请参阅 this Meta thread 关于该场景的详细信息。
标签: java optimization set performance