4

我刚刚在 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)
}
4

2 回答 2

5

好吧,您不能将像 2 的总和这样的简单运算与2 个集合Ints的运算进行比较。union我希望这些操作的性能会有很大不同,特别是如果您的 Set 包含很多元素。

你不需要联合,因为你已经做了一个交叉点。尝试以下操作:

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)......

于 2012-08-31T15:51:10.023 回答
0

您是否有机会使用并行集合?并集是以顺序方式执行的,因此任何并行集合首先转换为顺序集合。这可能是性能的原因。

除此之外,联合大约是 O(n),所以你要从 O(n) 到 O(1),这会产生很大的不同。

于 2012-09-01T02:51:17.723 回答