我刚刚在Scala Set API中遇到了一个奇怪的行为。这是我的功能剥离了与项目其余部分相关的内容
def grade(...): Double = {
val setA: HashSet = // get from somewhere else
val setB: HashSet = // get from somewhere else
if ((setA size) == 0 || (setB size) == 0) return 0
else return (setA & setB size) / (setA | set B size)
}
这个函数在循环内被调用很多次,整个循环在4.5秒左右执行。但是当用大小的总和(粗略近似)替换并集的大小时,为了测试并集操作的影响,执行时间减少到大约0.35秒......
def grade(...): Double = {
val setA: HashSet = // get from somewhere else
val setB: HashSet = // get from somewhere else
if ((setA size) == 0 || (setB size) == 0) return 0
else return (setA & setB size) / (setA size + set B size)
}
答案 0 :(得分:5)
好吧,你无法将简单的操作(例如2 Ints
的总和与2集的union
操作进行比较。我希望这些操作的性能大不相同,特别是如果你的集合包含很多元素。
你不需要工会,因为你已经做了一个交集。请尝试以下方法:
def grade: Double = {
val setA: HashSet = // get from somewhere else
val setB: HashSet = // get from somewhere else
if ((setA size) == 0 || (setB size) == 0) return 0
else {
val inter = setA & setB size
return inter / ((setA size) + (setB size) - inter)
}
}
然而,我发现你的测量有点奇怪,因为我预计两个操作(并集和交叉)需要大约相同的时间O(n)。删除联合应该可以将性能提高一半(2s)......
答案 1 :(得分:0)
您是否正在使用并行集合?联合以顺序方式执行,因此任何并行收集首先转换为顺序集合。这可能是表现的原因。
除此之外,union是关于O(n)的,所以你从O(n)到O(1),这会产生很大的不同。