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)。ユニオンを削除すると、パフォーマンスが半分 (2 秒) 向上するはずです...

于 2012-08-31T15:51:10.023 に答える
0

並列コレクションを使用していますか? 結合は順次に実行されるため、並列コレクションは最初に順次コレクションに変換されます。それがパフォーマンスの原因かもしれません。

それ以外では、結合は O(n) に関するものなので、O(n) から O(1) に変換することになり、大きな違いが生じます。

于 2012-09-01T02:51:17.723 に答える