3

注: Akka のチュートリアル コードをテスト ケースとして使用しますが、私の質問は、一般的な Scala の不変性のパフォーマンスと、結果として JVM を調整する方法についてです。

私は Akka に近づき、そのチュートリアル コードAkka を開始しようとしていました。チュートリアルのソース コードをそのまま自分のプロジェクトに貼り付けて実行すると、次の出力が得られました。

Calculation time:       660 milliseconds

この後、この関数を書き直して、コードに少し手を加えてみました

def calculatePiFor(start: Int, nrOfElements: Int): Double = {
  var acc = 0.0
  for (i <- start until (start + nrOfElements))
    acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1)
  acc
}

このように、変数アキュムレータを使用せずに

def calculatePiFor(start: Int, nrOfElements: Int): Double = {
  val range = start until (start + nrOfElements)
  val computation = range.map(i => 4.0 * (1 - (i % 2) * 2) / (2 * i + 1))
  computation.sum
}

まあ、それは機能しましたが、パフォーマンスは一種の退化しました

Calculation time:       1737 milliseconds

ここで私の質問があります。私の機能に重大な誤りがあるか、または間違いなくこれらのパフォーマンスにつながる何かがありますか? そうでない場合、これらのパフォーマンスを向上させるために JVM を調整するための適切なルールを誰か指摘できますか?

sbt 0.12.0 とデフォルトの Java オプション (sbt.bat にバンドル) を使用して、Scala 2.9 でコードを実行しました。

_JAVA_OPTS=-Xmx512M -XX:MaxPermSize=256m -XX:ReservedCodeCacheSize=128m

前もって感謝します

4

3 に答える 3

7

foldLeftあなたが示した必須の例として、1回のパスで合計を計算する which を使用することで、より良いパフォーマンスが得られます。

val computation = range.foldLeft(0.0){
  case (sum,i) => sum + 4.0 * (1 - (i % 2) * 2) / (2 * i + 1))
}

ただし、命令型の対応物よりもまだ遅い場合があります。それが実際にアプリケーションのボトルネックである場合は、最も高速なバージョン (while ループを使用した命令型バージョン) を使用する必要があります。変更可能な状態は完全に分離されるため、アクタでは安全です。

他のすべてのケースでは、(アプリケーション全体で測定した場合に) 数パーセントのパフォーマンスを失って、乱雑なコードを使用することをお勧めします。

于 2012-11-16T11:04:54.303 に答える
2

あなたのプログラムの問題は、厳密な(非遅延)range.map(..)メソッドの呼び出しだと思います。つまり、範囲に 1000 個の要素がある場合、メソッドは 1000 個の新しい要素にメモリを割り当て、それらすべてをすぐに計算します。map

したがって、コードを改善する代替の非常に簡単な方法は、範囲ビューを使用することであると思います。range.view.map(..)これにより、マップされた要素が遅延して計算され、一定量のメモリが割り当てられます。

于 2012-11-16T11:31:04.203 に答える
1

map/sum の代わりに foldLeft を試すことができます:

  def calculatePiFor(start: Int, nrOfElements: Int): Double = {
    val range = start until (start + nrOfElements)
    range.foldLeft(0.0) { (acc,i) => acc + 4.0 * (1 - (i % 2) * 2) / (2 * i + 1)}
  } 

これにより、中間コレクションの必要性が回避されるため、より高速に実行される可能性があると思います。

于 2012-11-16T11:17:04.680 に答える