[0.2]Scala言語の面からSparkの計算の魅力を体験する

7225 ワード

リファレンス
Collections Stream API Memoizationテクノロジーの詳細
シーン
Spark RDDは分布式のscala集合に相当し,Spark自体はscalaで書かれている.本稿では、集合要素scalaについて試みる.collection.immutable.Streamの使用例として、scala言語レベルから内蔵された遅延計算とMemoization体験Sparkの強力な計算能力!
  • 遅延計算遅延計算は計算中間結果の発生を避けることができ、計算中間過程が複雑または長いプログラムの中で最も遅延計算の功力を体現することができる.scalaでlazyキーワードで修飾されたエンティティは、遅延計算の特性を有します.
  • memoization memoizationは、以前の演算結果をキャッシュできる技術であり、計算済みの結果を再計算する必要がない.
  • Stream類を認識本文はscala.collection.immutable.Stream類を使い、実験でlazyとmemoizationの魅力を体験.「Stream implements lazy lists where elements are only evaluated when they are needed.」簡単に言えばlazy版のscalaに相当する.collection.immutable.List .

  • この文章の編纂はまったく意外です:Stream類の操作を学ぶ時滴を発見します!ははは!
    じっけん
    Streamプローブ
    Streamの作成:
    scala> val strm = 1#::2#::Stream.empty
    strm: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    
    scala> (1 to 100).toStream.map(i=> i*3+7).filter(i=> (i%10)==0).sum
    res6: Int = 1450
    
    scala> 
    

    「フィボナッチ数列」の上位7項目を印刷することを例に、2つの方法で実現し、Stream:-def版の実現をさらに認識する.
    scala> def fibs(a:BigInt,b:BigInt):Stream[BigInt]=a#::fibs(b,a+b)
    fibs: (a: BigInt, b: BigInt)Stream[BigInt]
    
    scala> fibs(0,1) take 7 foreach println
    0
    1
    1
    2
    3
    5
    8
    scala> 
  • val版実現(不思議な実現方法ですね-まだ完全に理解されていません)
  • scala> val fibs:Stream[BigInt]=BigInt(0)#::BigInt(1)#::fibs.zip(fibs.tail).map(n=>n._1 +n._2)
    fibs: Stream[BigInt] = Stream(0, ?)
    
    scala> fibs(7)
    res4: BigInt = 13
    
    scala> fibs take 7 foreach println
    0
    1
    1
    2
    3
    5
    8
    scala> 

    ちえんけいさん
    “The class ” scala.collection.immutable.Streamはlazy版のscalaに相当する.collection.immutable.List.ここではStreamの使用を例に、lazyの魅力を説明します!:
    scala> Range(1,50000000).filter(_%2==0)(1)
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    
    scala> Stream.range(1,50000000).filter(_%2==0)(1)
    res44: Int = 4 //1 50000000      2     

    文:Range(1,50000000).filter(_%2==0)(1)の実行は直接OOMを招いた!そして文:Stream.range(1,50000000).filter(_%2==0)(1)結果を正しく計算!?Stream.range(1,50000000)5,000,000,000,000のすべての整数を列挙していないため:scala> Stream.range(1,50000000)
    res3: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    文:Stream.range(1,50000000).filter(_%2==0)第1ステップのみ実行した:scala> Stream.range(1,50000000).filter(_%2==0)
    res5: scala.collection.immutable.Stream[Int] = Stream(2, ?)
    memoization
    memoizationは、以前に計算した結果をキャッシュできる技術であり、計算した結果を再計算する必要はありません.Mr.SnailはStream内部でmemoization技術を用いて反復計算の速度を向上させると推測した.ここでは12番目のフィボナッチ数を例に、説明します!
     scala> val fibs:Stream[BigInt]=BigInt(0)#::BigInt(1)#::fibs.zip(fibs.tail).map(n=>{println("Adding %d and %d".format(n._1,n._2));n._1+n._2})
    fibs: Stream[BigInt] = Stream(0, ?)
    
    scala> fibs(5)
    Adding 0 and 1
    Adding 1 and 1
    Adding 1 and 2
    Adding 2 and 3
    res9: BigInt = 5
    
    scala> fibs(10)
    Adding 3 and 5
    Adding 5 and 8
    Adding 8 and 13
    Adding 13 and 21
    Adding 21 and 34
    res10: BigInt = 55
    
    scala> fibs(12)
    Adding 34 and 55
    Adding 55 and 89
    res11: BigInt = 144
    

    ここでは,10番目のフィボナッチ数を先に計算し,12番目の計算を先に直接計算した上で(Memoization技術を用いて前の演算結果をキャッシュした)計算したので,最初から計算するのではなく,効率が極めて高い!
    まとめ
    scalaには関数式プログラミングのいくつかの精髄が導入されている:lazy、momoizationなど、これはいくつかの計算シーンを処理し、eg、反復計算を行い、高い効率を持っている-ビッグデータ計算フレームワークSparkはscala言語自体の優れた特性を大きく得意としている.