6

なぜですか

for (
  a <- 1 to 1000;
  b <- 1 to 1000 - a;
  c <- 1 to 1000 - a - b;
  if (a * a + b * b == c * c && a + b + c == 1000)
) println((a, b, c, a * b * c))

266ミリ秒

その後遅い:

for (a <- 1 to 1000)
  for (b <- 1 to 1000 - a)
    for (c <- 1 to 1000 - a - b)
      if (a * a + b * b == c * c)
        if (a + b + c == 1000)
          println((a, b, c, a * b * c))

62ミリ秒

私が正しいと理解しているなら、これは同じであるはずですか?


回答を処理した後の解決策:

for (
  a <- 1 to 1000;
  b <- 1 to (1000 - a)
) {
  val c = (1000 - a - b)
  if (a * a + b * b == c * c)
    println((a, b, c, a * b * c))
}

9ミリ秒

4

2 に答える 2

14

あなたの理解は間違っています。

これは、条件がループ本体にある場合に発生します。

// this
for(x <- coll) if(condition) doSomething
// will translate to
coll.foreach{ x => if(condition) doSomething }

条件がジェネレータ自体にある場合とは対照的に、次のようになります。

// this
for(x <- coll if(condition)) dosomething
// will translate to
coll.withFilter(x => condition).foreach{ x => dosomething }

詳細については、 Scala言語仕様6.16を参照してください。

于 2013-02-28T14:04:47.917 に答える
11

forループが内部で変換される方法の詳細については、このプレゼンテーション(スライド13〜15)を確認することをお勧めします。

例の主な違いは次のとおりです。

  • forループ本体の条件(2.例)
  • ジェネレーター内の状態(1.例)

後者は、ループフィルタリングとも呼ばれ、設計上、パフォーマンス上の欠点があります。起こっていることを非常に単純化するために:(withFilter変換の最初のステップである)内に、タイプの匿名の新しい関数Function2[Object, Boolean]が作成されます(これは条件を評価するために使用されます)。関数に渡されるパラメーターはapply、に基づいて定義されるため、ボックス化する必要がありますObjectifこのボクシング/アンボクシングは、変数に直接アクセスできるforループ本体内で条件を直接評価するよりもはるかに低速です。

于 2013-02-28T14:06:15.370 に答える