5

私は最近さまよっていました.ScalaはJVMで実行され、後者はいくつかのタイプの操作に最適化されているため、JVMでの実装が本当に非効率的であり、したがって使用をお勧めできない機能はありますか? また、なぜ非効率なのか説明していただけますか?

最初の候補は関数型プログラミング機能です。私が知っているように、関数はapplyメソッドを持つ特別なクラスであり、関数が単なるコードのブロックである言語と比較して、明らかに追加のオーバーヘッドが発生します。

4

1 に答える 1

8

パフォーマンス チューニングは深く複雑な問題ですが、すぐに 3 つのことが思い浮かびます。

Scala コレクションは表現力には優れていますが、パフォーマンスには適していません。

検討:

(1 to 20).map(x => x*x).sum

val a = new Array[Int](20)
var i = 0
while (i < 20) { a(i) = i+1; i += 1 }  // (1 to 20)
i = 0
while (i < 20) { a(i) = a(i)*a(i); i += 1 }   // map(x => x*x)
var s = 0
i = 0
while (i < 20) { s += a(i); i += 1 }  // sum
s

最初のものは驚くほどコンパクトです。2 番目は 16 倍高速です。整数の計算は非常に高速です。ボクシングとアンボクシングはありません。ジェネリック コレクション コードは、まあ、ジェネリックであり、ボクシングに依存しています。

Function2 は、Int、Long、および Double 引数のみに特化しています。

プリミティブに対するその他の操作には、ボクシングが必要です。注意してください!

機能を切り替えることができる関数が必要だとします。文字を大文字にするかどうかなどです。試してみて:

def doOdd(a: Array[Char], f: (Char, Boolean) => Char) = {
  var i = 0
  while (i<a.length) { a(i) = f(a(i), (i&1)==1); i += 1 }
  a
}

そして、あなた

val text = "The quick brown fox jumps over the lazy dog".toArray
val f = (c: Char, b: Boolean) => if (b) c.toUpper else c.toLower

scala> println( doOdd(text, f).mkString )
tHe qUiCk bRoWn fOx jUmPs oVeR ThE LaZy dOg

よしよし!もし私たちが

trait Func_CB_C { def apply(c: Char, b: Boolean): Char }
val g = new Func_CB_C {
  def apply(c: Char, b: Boolean) = if (b) c.toUpper else c.toLower
}
def doOdd2(a: Array[Char], f: Func_CB_C) = {
  var i = 0
  while (i<a.length) { a(i) = f(a(i), (i&1)==1); i += 1 }
  a
}

代わりは?一気に3倍速くなりました。しかし、それが(Int, Int) => Int, (または Int/Long/Double 引数と Unit/Boolean/Int/Long/Float/Double 戻り値のその他の順列) の場合、独自のローリングは不要です。特殊化されており、最大速度で動作します。

簡単に並列化できるからといって、それが良い考えであるとは限りません。

Scala の並列コレクションは、コードを並列に実行しようとします。並行して実行するのが賢明なことであるように、十分な作業があることを確認するのはあなた次第です。スレッドのセットアップと結果の収集には多くのオーバーヘッドがあります。たとえば、

val v = (1 to 1000).to[Vector]
v.map(x => x*(x+1))

val u = (1 to 1000).to[Vector].par
u.map(x => x*(x+1))

2 番目のマップの方が高速ですよね。平行だからですか?

しそうにない!オーバーヘッドのために10倍遅くなります(私のマシンでは、結果は大幅に異なる場合があります)

概要

これらは、コードの最もパフォーマンスが重要な部分を除いて、通常は気にする必要のない非常に多くの問題のほんの一部です。もっとたくさんありますが、最終的にはあなたが遭遇するでしょうが、私のコメントで述べたように、それらのかなりの部分をカバーするには本が必要です. どの言語にもパフォーマンスの問題が山ほどあり、最適化はしばしば難しいことに注意してください。重要なところに労力を節約しましょう。

于 2013-04-25T14:11:38.147 に答える