Pro Yearly is on sale from $80 to $50! »

Scalaでの並行・並列処理戦略/strategy-for-concurrency-and-parallel-by-scala

Ca4df28501e4c9cfbceb91f367afa784?s=47 fuzyco
November 10, 2018

 Scalaでの並行・並列処理戦略/strategy-for-concurrency-and-parallel-by-scala

Scala関西サミット2018で発表したスライドです。

Ca4df28501e4c9cfbceb91f367afa784?s=128

fuzyco

November 10, 2018
Tweet

Transcript

  1. ScalaͰͷ ฒߦɾฒྻॲཧઓུ Scalaؔ੢Summit 2018 ౻໺޺थ 

  2. ࣗݾ঺հ  • ౻໺޺थ • αʔόʔαΠυΤϯδχΞ@Fringe81 • Scalaྺ2೥ • ਓੜॳͷେࡕ

  3. Ϟνϕʔγϣϯ  Scala͸ฒߦɾฒྻॲཧΛߦ͏ͨΊͷϥΠϒϥϦ͕๛෋ʁ

  4. Ϟνϕʔγϣϯ  Scala͸ฒߦɾฒྻॲཧΛߦ͏ͨΊͷϥΠϒϥϦ͕๛෋ʁ ‣ ฒߦɾฒྻॲཧΛ࣮ݱ͢ΔϥΠϒϥϦ •ඪ४ϥΠϒϥϦ •Future •ฒྻίϨΫγϣϯ •ϥΠϒϥϦ •Akka

    Actor •Monix
  5. Ϟνϕʔγϣϯ  Scala͸ฒߦɾฒྻॲཧΛߦ͏ͨΊͷϥΠϒϥϦ͕๛෋ʁ ‣ ฒߦɾฒྻॲཧΛ࣮ݱ͢ΔϥΠϒϥϦ •ඪ४ϥΠϒϥϦ •Future •ฒྻίϨΫγϣϯ •ϥΠϒϥϦ •Akka

    Actor •Monix Ͳ͏࢖͍෼͚Δͷ͔ Θ͔Βͳ͍
  6. ScalaͷϥΠϒϥϦ͸ศར  தͷ࢓૊ΈͳͲΛߟ͑ͳͯ͘΋ͱΓ͋͑ͣ؆୯ʹ࢖͑Δ Future => Future.apply͢Ε͹ผεϨουͰॲཧ͕૸Δ Akka Actor => ඇಉظϝοηʔδύογϯά͕Ͱ͖Δ

    ฒྻίϨΫγϣϯ => .par͢Ε͹ฒྻॲཧ͕Ͱ͖Δ
  7. ى͖Δࣄ৅  •Future಺ͰThread.sleep͢ΔͱɺεϨουރׇͨ͠ •͜ͷॲཧAkka ActorͱFutureͲͬͪͰ΍Δ΂͖ͳͷ͔Θ͔Βͳ͍ •ฒྻίϨΫγϣϯ࢖ͬͨΒٯʹ஗͘ͳͬͨ ͱΓ͋͑ͣ࢖͏͚ͩ͸ྑ͘ͳͦ͞͏

  8. ग़ͯ͘Δٙ໰  w 'VUVSFʹ͸*NQMJDJUTHMPCBMΛ౉͓͚ͯ͠͹͍͍ͷ͔ʁ w ͱΓ͋͑ͣ"LLB"DUPS࢖͑͹͍͍ͷ͔ʁ w ฒྻίϨΫγϣϯ࢖͏ͱ଎͘ͳΔέʔεͱ͸ʁ w ඇಉظॲཧͰΑ͘ग़ͯ͘Δ&YFDVUJPO$POUFYUͬͯԿͳͷʁ

    ࢓૊ΈΛཧղ͢Ε͹ΑΓΑ͍׆༻͕Ͱ͖Δ
  9. ൃද಺༰  ࿩͢͜ͱ ࿩͞ͳ͍͜ͱ • ScalaͷฒߦɾฒྻॲཧϥΠϒϥϦ •ಛ௃ •࢓૊Έ •Ϣʔεέʔε •ϥΠϒϥϦͷࡉ͔͍࢓༷/tips

    •௿ϨΠϠͷ࿩(OSϨϕϧ) •ύϑΥʔϚϯενϡʔχϯά
  10. ຊൃදͷΰʔϧ  FutureɺAkka ActorͳͲͷฒߦɾฒྻϥΠϒϥϦͷಛ௃ɾ࢓૊ΈΛ ཧղɺ੔ཧͯ͠ΑΓ҆શͰ଎͍γεςϜ࡞Γͷॿ͚ʹͳΕ͹޾͍Ͱ͢

  11. ͓඼ॻ͖  • ฒߦɾฒྻॲཧͱ͸ • ScalaͷฒߦɾฒྻϥΠϒϥϦ • ExecutionContextʹ͍ͭͯ • ·ͱΊ

  12. ͓඼ॻ͖  • ฒߦɾฒྻॲཧͱ͸ • ScalaͷฒߦɾฒྻϥΠϒϥϦ • ExecutionContextʹ͍ͭͯ • ·ͱΊ

  13. ྺ࢙తഎܠ  ूੵճ࿏্ͷτϥϯδελ਺͸ʮ18͔݄ʢ=1.5೥ʣ͝ͱʹഒʹͳΔʯ Կ΋͠ͳͯ͘΋ϓϩάϥϜ͕଎͘ͳ͍ͬͯ͘ ϜʔΞͷ๏ଇ [Ҿ༻: https://ja.wikipedia.org/wiki/%E3%83%A0%E3%83%BC%E3%82%A2%E3%81%AE%E6%B3%95%E5%89%87]

  14. ྺ࢙తഎܠ  ๏ଇʹԊͬͯCPUͷॲཧੑೳ্͕͕Βͳ͘ͳͬͨ “The Free Lunch Is Over” Կ΋͠ͳͯ͘΋ϓϩάϥϜ͕଎͘ͳΒͳ͍ ϚϧνίΞCPUΛ׆༻ͨ͠ฒߦɾฒྻॲཧ͕ඞཁ

    ϜʔΞͷ๏ଇͷ่յ
  15. ϚϧνίΞCPUΛ׆༻ͨ͠ ฒߦɾฒྻॲཧ  CPU CPU1 CPU2 ҰͭͷCPU͕εϨουΛ੾Γସ͑ͳ͕Βෳ਺ͷλεΫΛ࣮ߦ͢Δ εϨουΛCPUͷίΞʹ౰ͯͯɺಉ࣌ʹλεΫΛ࣮ߦ͢Δ ฒߦॲཧ(concurrent) ฒྻॲཧ(parallel)

    εϨου1 εϨου2 ࣌ؒ ࣌ؒ ※ฒߦ͸ฒྻΛแؚ͢Δ
  16. ฒߦɾฒྻॲཧͷ೉͠͞  • εϨουηʔϑ͕ٻΊΒΕΔ • σʔλڝ߹ʢϨʔείϯσΟγϣϯʣ • σουϩοΫ • εϨουੜ੒ɺ؅ཧͷίετ

  17. σʔλڝ߹ʢϨʔείϯσΟγϣϯʣ  ෳ਺ͷεϨου͔ΒಉҰϦιʔεʹΞΫηε͢Δͱɺ ༧ظ͠ͳ͍ঢ়ଶ(σʔλڝ߹)ʹͳΔ͜ͱ͕͋Δ λΠϛϯάͷ໰୊Ͱى͖ΔͷͰɺ࠶ݱ͢Δͷ͕೉͍͠ εϨου̍ εϨου2 ޱ࠲࢒ߴ 10000 ࢒ߴ֬ೝ

    -8000 -5000 ޱ࠲࢒ߴ -3000 OK ࢒ߴ֬ೝ OK
  18. ϩοΫػߏ  σʔλڝ߹Λͳͨ͘͢Ίʹڞ༗Ϧιʔεʹରͯ͠ ϩοΫΛͯ͠ಉظΛߦ͏ •ೋͭͷεϨου͕͓ޓ͍ʹϩοΫͷղ์Λ଴ͪଓ͚ΔʢσουϩοΫʣ •ϩοΫΛ෇͚๨ΕΔ •ա৒ͳϩοΫΛߦ͏͜ͱʹΑΔεϧʔϓοτͷ௿Լ ϓϩάϥϚʔ͕৭ʑؤுΒͳ͍ͱ͍͚ͳ͍

  19. Scalaʹ͸ ฒߦɾฒྻॲཧͷ೉఺Λαϙʔτ͢Δ ϥΠϒϥϦ͕͍͔ͭ͘ଘࡏ͠·͢ 

  20. ͓඼ॻ͖  • ฒߦɾฒྻॲཧͱ͸ • ScalaͷฒߦɾฒྻϥΠϒϥϦ • ExecutionContextʹ͍ͭͯ • ·ͱΊ

  21.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5]

  22.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5] ద༻ൣғ͕૿͍ͯ͘͠

  23.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5] ద༻ൣғ͕૿͍ͯ͘͠ ίϨΫγϣϯʹ ର͢Δฒྻॲཧ ঢ়ଶΛ࣋ͨͳ͍ ฒߦॲཧ ঢ়ଶΛ࣋ͬͨ

    ฒߦॲཧ
  24.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5] ίϨΫγϣϯʹ ର͢Δฒྻॲཧ

  25. ScalaฒྻίϨΫγϣϯ  • ฒྻॲཧΛ࣮ݱ͢ΔίϨΫγϣϯϥΠϒϥϦ • Scala2.9͔Βಋೖ͞Εͨ

  26. ScalaίϨΫγϣϯ  ɾList, Array, etc. scala> val list = (1

    to 10000).toList list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, … scala> list.map(_ + 42) res0: List[Int] = List(43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, … scala> list.max res1: Int = 10000
  27. ScalaฒྻίϨΫγϣϯ  ίϨΫγϣϯͷԋࢉΛฒྻʹ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ scala> val parList = list.par parList: scala.collection.parallel.immutable.ParSeq[Int]

    = ParVector(1, 2, 3, 4, 5, …) scala> parList.seq res1: scala.collection.immutable.Seq[Int] = Vector(1, 2, 3, 4, 5, 6, … ) ม׵͕Մೳ scala> parList.foreach(elm => print(s"$elm ")) 376 377 501 813 876 2 … ฒྻʹॲཧ͕࣮ߦ͞ΕΔ
  28. ScalaฒྻίϨΫγϣϯ  import scala.util.Random val numbers = Random.shuffle(Vector.tabulate(10000000)(i => i))

    val seqtime = measure { numbers.max } log(s"Sequential time ${seqtime.value} ms”) val partime = measure { numbers.par.max } log(s"Parallel time ${partime.value} ms") Sequential time 535.850688 ms Parallel time 193.393754 ms parϝιουΛ࢖͚ͬͨͩͰ ฒྻʹॲཧ͕ߦΘΕΔ ϥϯμϜͳ஋ͷཁૉΛ10000000ݸ࣋ͭVectorͷ ࠷େͷཁૉΛٻΊΔϓϩάϥϜ
  29. ฒྻॲཧ  ฒྻԽͰ͖ΔλεΫΛׂΓग़ͯ͠ɺ ޮ཰Α͘෼ׂͯ͠ฒྻʹ࣮ߦ͢Δඞཁ͕͋Δ ΞϜμʔϧͷ๏ଇ ฒྻίϨΫγϣϯ͸಺෦Ͱ෼ׂ౷࣏ͷΞϓϩʔνʹج͍ͮͯίϨΫγϣϯΛ ޮ཰Α͘෼ׂͯ͠ฒྻʹԋࢉΛߦ͏

  30. ෼ׂ౷࣏๏  ໰୊Λ෼ׂͯ͠ɺͦΕͧΕಠཱͯ͠ࢉग़͞ΕͨղΛ ౷߹͍ͯ͘͠Ξϓϩʔν(ྫ: Ϛʔδιʔτ) ෦෼ ղ ղ ෦෼ ղ

    ෦෼ ղ ෦෼ ղ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊
  31. ෼ׂ౷࣏  ໰୊Λ෼ׂͯ͠ɺͦΕͧΕಠཱͯ͠ࢉग़͞ΕͨղΛ ౷߹͍ͯ͘͠Ξϓϩʔν(ྫ: Ϛʔδιʔτ) ෦෼ ղ ղ ෦෼ ղ

    ෦෼ ղ ෦෼ ղ ฒྻԽՄೳ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊ ෦෼ ໰୊
  32. ෼ׂ౷࣏  ߹ܭ஋ શମͷ ߹ܭ஋ ߹ܭ஋ ߹ܭ஋ ߹ܭ஋ ֤CPUͰฒྻʹ࣮ߦ "SSBZ

    ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ sumϝιουݺͼग़͠ʹΑΔίϨΫγϣϯͷ߹ܭ஋ͷܭࢉ ArrayΛεϨου ͷ਺͚ͩ෼ׂ ͦΕͧΕͷ߹ܭ஋ Λ଍͠߹ΘͤΔ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ
  33. ෼ׂ౷࣏  ෼ׂ౷࣏͸ɺ෼ׂ͞ΕͨλεΫ͕ಠཱͯ͠ ࣮ߦͰ͖Δܭࢉʹ޲͘ •ݕࡧ/બ୒ => ෼ׂ͞Εͨ୯ҐͰݕࡧ/બ୒Մೳ •ιʔτ => ෼ׂ͞ΕͨλεΫ୯ҐͰιʔτՄೳ

    •ूܭ => ෼ׂ͞ΕͨλεΫ୯ҐͰूܭՄೳ
  34. ฒྻίϨΫγϣϯͷ࢓૊Έ  Splitter ෼ׂ౷࣏Λ࣮ݱ͍ͯ͠ΔΦϒδΣΫτ trait IterableSplitter[T] extends Iterator[T] { def

    dup: IterableSplitter[T] def remaining: Int def split: Seq[IterableSplitter[T]] } ίϨΫγϣϯΛޮ཰Α͘෼ׂ͢Δ Combiner trait Combiner[-Elem, +To] extends Builder[Elem, To] with Sizing with Parallel { def combine[N <: Elem, NewTo >: To](other: Combiner[N, NewTo]): Combiner[N, NewTo] } ෼ׂ͞ΕͨλεΫͷԋࢉ݁ՌΛ݁߹͢Δ
  35. ฒྻίϨΫγϣϯϋϚΓϙΠϯτ  • ଎౓͕͕͋Δͱ͸ݶΒͳ͍ • ૝ఆ͍ͯͨ͠ܭࢉ݁ՌʹͳΒͳ͍ Ϣʔεέʔε͕ݶఆ͞ΕΔ෼ɺޡͬͨ࢖͍ํ͕ଘࡏ͢Δ

  36. ଎౓͕͕͋Δͱ͸ݶΒͳ͍  • εϨουؒͷಉظॲཧ(σʔλڝ߹) • ฒྻίϨΫγϣϯ΁ͷม׵ίετ

  37. εϨουؒͷಉظॲཧ (σʔλڝ߹)  object ParUid extends App { private val

    uid = new AtomicLong(0L) val seqtime = measure { for(i <- 0 until 10000000) uid.incrementAndGet() } println(s"Sequential time ${seqtime.value} ms”) val partime = measure { for(i <- (0 until 10000000).par) uid.incrementAndGet() } println(s"Parallel time ${partime.value} ms") } ※measureؔ਺͸ScalaMeterͷॲཧ࣌ؒΛܭଌ͢Δؔ਺ uidΛAtomicม਺Ͱ҆શͳಉظΛ ߦͬͯΧ΢ϯτΞοϓ͍ͯ͠Δ ϧʔϓॲཧͰΧ΢ϯτΞοϓ͢ΔϓϩάϥϜ
  38. εϨουؒͷಉظॲཧ (σʔλڝ߹)  4FRVFOUJBMUJNFNT 1BSBMMFMUJNFNT object ParUid extends App {

    private val uid = new AtomicLong(0L) val seqtime = measure { for(i <- 0 until 10000000) uid.incrementAndGet() } println(s"Sequential time ${seqtime.value} ms”) val partime = measure { for(i <- (0 until 10000000).par) uid.incrementAndGet() } println(s"Parallel time $partime ms") } ฒྻίϨΫγϣϯΛ࢖ͬͨ΄͏͕ ͕͔͔͍࣌ؒͬͯΔ εϨουؒͰσʔλΛਖ਼͘͠ڞ༗͢ΔͨΊʹಉظΛߦ͏ͷͰɺ ֤εϨουͰॲཧ଴͕ͪൃੜͯ͠εϧʔϓοτ͕௿Լ͢Δ
  39. ฒྻίϨΫγϣϯ΁ͷม׵ίετ  ListͱVectorΛͦΕͧΕ ฒྻίϨΫγϣϯʹม׵͢ΔϓϩάϥϜ object ParNonParallelizableCollections extends App with Logger

    { val list = List.fill(1000000)("") val vector = Vector.fill(1000000)(“") println(s"list conversion time: ${measure(list.par).value} ms") println(s"vector conversion time: ${measure(vector.par).value} ms") }
  40. ฒྻίϨΫγϣϯ΁ͷม׵ίετ  MJTUDPOWFSTJPOUJNFNT WFDUPSDPOWFSTJPOUJNFNT ListͱVectorΛͦΕͧΕ ฒྻίϨΫγϣϯʹม׵͢ΔϓϩάϥϜ object ParNonParallelizableCollections extends App

    with Logger { val list = List.fill(1000000)("") val vector = Vector.fill(1000000)(“") println(s"list conversion time: ${measure(list.par).value} ms") println(s"vector conversion time: ${measure(vector.par).value} ms") } ListͷฒߦίϨΫγϣϯ΁ͷม׵ ʹ͔ͳΓ͕͔͔͍࣌ؒͬͯΔ
  41. ฒྻίϨΫγϣϯ΁ͷม׵ίετ  ฒྻίϨΫγϣϯͷ࣮૷ Λ࣌ͨͳ͍ίϨΫγϣϯ ฒྻίϨΫγϣϯͷ࣮૷ Λ࣋ͭίϨΫγϣϯ ฒྻίϨΫγϣϯ List Vector ParVector

    scala> (1 to 10000).toList.par res2: ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, …
  42. ฒྻίϨΫγϣϯ΁ͷม׵ίετ  List Vector ParVector scala> (1 to 10000).toList.par res2:

    ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, … શͯͷཁૉΛίϐʔ͢ΔͷͰܭࢉίετ͕͔͔Δ ฒྻίϨΫγϣϯͷ࣮૷ Λ࣌ͨͳ͍ίϨΫγϣϯ ฒྻίϨΫγϣϯͷ࣮૷ Λ࣋ͭίϨΫγϣϯ ฒྻίϨΫγϣϯ
  43. ฒྻίϨΫγϣϯͷ࣮૷Λ࣋ͭ ίϨΫγϣϯ  ্هҎ֎ͷίϨΫγϣϯͷฒྻίϨΫγϣϯ΁ͷ ม׵͸͕͔͔࣌ؒΔ •Array •ArrayBuffer •Vector •mutable.HashMap •immutable.HashMap

    •Range •mutable.HashSet •immutable.HashSet •concurrent.TrieMap
  44. ૝ఆ͍ͯͨ͠ܭࢉ݁ՌʹͳΒͳ͍  • ঢ়ଶΛѻ͏ԋࢉ • ݁߹ଈ͕੒ཱ͠ͳ͍ԋࢉ

  45. ঢ়ଶΛѻ͏ԋࢉ  scala> var sum = 0 sum: Int =

    0 scala> val parList = (1 to 1000).toList.par parList: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5, … scala> var sum = 0 sum: Int = 0 scala> parList.foreach(sum += _); sum res01: Int = 307792 scala> parList.foreach(sum += _); sum res02: Int = 417753
  46. ঢ়ଶΛѻ͏ԋࢉ  ద੾ʹಉظΛऔΔͱࠓ౓͸ॲཧ଎౓͕٘ਜ਼ʹͳΔ ಺෦Ͱঢ়ଶΛѻ͏ԋࢉ͸ద੾ʹಉظΛऔΒͳ͚Ε͹ͳΒͳ͍ɹ ฒྻίϨΫγϣϯ͸֤λεΫͰ७ਮͳܭࢉΛ͢Δ΂͖

  47. ݁߹ଇ͕੒Γཱͨͳ͍ԋࢉ  ฒྻͰ࣮ߦ͞ΕΔͷͰɺ݁߹཯͕੒Γཱͨͳ͍ԋࢉ͸ႈ౳ͳ஋ʹͳΒͳ͍ ྫ: (1-2)-3 != 1-(2-3) scala> val parList

    = (1 to 1000).toList.par parList: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5, … scala> parList.reduce(_ - _) res0: Int = -169948 scala> parList.reduce(_ - _) res1: Int = 181648
  48. ฒྻCollection·ͱΊ  • ฒྻίϨΫγϣϯ͸ιʔτɺݕࡧɺબ୒ɺूܭʹ޲͘ • ฒྻίϨΫγϣϯ಺ͰಉظॲཧΛߦ͏ͱࢥ͏Α͏ʹ଎͘ ͳΒͳ͍ • ฒྻίϨΫγϣϯͷ࣮૷Λ࣋ͨͳ͍ίϨΫγϣϯΛฒྻ ίϨΫγϣϯʹม׵͢Δͱࢥ͏Α͏ʹ଎͘ͳΒͳ͍

    • ঢ়ଶΛѻ͏ԋࢉ΍݁߹ଇ͕੒Γཱͨͳ͍ԋࢉͰ͸ඇܾఆ ੑʹͭͳ͕ΔՄೳੑ͕͋Δ
  49.  ฒྻCollectionͰIOॲཧ val userIds: List[String] = List("id") def findUser(userId: String):

    User = { database.findUser(userId) } val users = userIds.par.map { userId => findUser(userId) } CPU1 IO଴ͪ CPU2 IO଴ͪ ฒྻίϨΫγϣϯ಺ͰIOό΢ϯυͳॲཧΛߦ͏ͱɺ IO଴ͪͷؒશͯͷCPUͷॲཧ͕ఀࢭͯ͠͠·͏ DB΁ͷ ΞΫηε
  50.  Future IOό΢ϯυͳॲཧʹ͓͍ͯ͸ɺ 1CPU಺Ͱෳ਺ͷεϨουΛ੾Γସ͑ͯฒߦʹ࣮ߦ͢Δํ͕ޮ཰͕ྑ͍ ※ਤ͸ཧ૝Ͱ͋Γɺ ࣮ࡍ͸OSͷεέδϡʔϥ͕εϨουΛׂΓ౰ͯΔͷͰ ͜ͷΑ͏ʹ៉ྷʹׂΓ౰ͯΒΕΔͱ͸ݶΒͳ͍ CPU1 IO଴ͪ CPU2

    IO଴ͪ CPU1 εϨου1 εϨου2 IO଴ͪ CPU2 εϨου3 εϨου4 IO଴ͪ
  51.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5] ঢ়ଶΛ࣋ͨͳ͍ ฒߦॲཧ

  52. Future  ඇಉظॲཧΛ࣮ݱ͢Δඪ४ϥΠϒϥϦ •಺෦ͰεϨουϓʔϧΛ༻͍ͨඇಉظॲཧͷ࣮ݱ •εϨουͷ؅ཧɺׂΓ౰ͯΛҙࣝ͠ͳ͍ •ϓϩάϥϚ͸ඇಉظʹ࣮ߦ͍ͨ͠λεΫʹूதͰ͖Δ •mapɺflatMapʹΑΔ߹੒Մೳੑ

  53. Future  import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global object FutureSample extends App

    { Future { println(s"[ThreadName] In Future: ${Thread.currentThread.getName}") println(1) } println(s"[ThreadName] In Main: ${Thread.currentThread.getName}") println(2) } Future.applyͰғΉͱɺผεϨουͰඇಉظॲཧ͕૸Δ [ThreadName] In Main: main 2 [ThreadName] In Future: scala-execution-context-global-11 1 ͜͜͸ ผεϨου
  54. Future  MainεϨου ผεϨου println(1) println(2) object FutureSample extends App

    { Future { println(s"[ThreadName] In Future: ${Thread.currentThread.getName}") println(1) } println(s"[ThreadName] In Main: ${Thread.currentThread.getName}") println(2) } Future.applyͰғΉͱɺผεϨουͰඇಉظॲཧ͕૸Δ
  55. Future  ҰͭͷCPUͰIOॲཧͷؒʹεϨουΛ੾Γସ͑ͯଞͷ࡞ۀΛ CPUʹׂΓ౰ͯΔ͜ͱʹΑͬͯɺεϧʔϓοτ͕޲্͢Δ ※ෳ਺ͷCPU͕͋Δ৔߹͸ɺͦΕͧΕCPUͰฒྻʹ࣮ߦ͞ΕΔ͜ͱ΋͋Δ CPU CPU Future1 Future2 IO଴ͪ

    IO଴ͪ
  56. Futureͷ߹੒Մೳੑ  map, flatMap ͋ΔεϨουͰͷඇಉظॲཧ͕੒ޭͨ͠Βɺ ͦͷܭࢉ݁ՌΛ࢖ͬͯผͷεϨουͰඇಉظॲཧΛ࣮ߦͰ͖ͯɺ ࣦഊͨ͠৔߹ʹ͸Failure(ࣦഊ)͕ฦΔ forࣜͰ΋ॻ͚Δ def map[S](f:

    T => S)(implicit executor: ExecutionContext): Future[S] def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S]
  57. Futureͷ߹੒Մೳੑ  map, flatMap def createResponse(user: User, team: Team): String

    val userF = Future { database.findUser("user1") } val teamF = Future { database.findTeam("team1") } val response = userF.flatMap { user => teamF.map { team => createResponse(user, team) } } response.foreach(println)
  58. Futureͷ߹੒Մೳੑ  ෳ਺ͷεϨουͰߦΘΕ͍ͯΔ ॲཧಉ࢜ͷ଴ͪ߹Θͤɺ Τϥʔͷ࣌ͷॲཧΛॻ͘ඞཁ͕ͳ͍ MainεϨου val userF val teamF

    val response Future.apply Future.apply database.findTeam user team response.onComplete flatMap map database.findUser def createResponse(user: User, team: Team): String val userF = Future { database.findUser("user1") } val teamF = Future { database.findTeam("team1") } val response = userF.flatMap { user => teamF.map { team => createResponse(user, team) } } response.foreach(println)
  59. Future಺Ͱͷঢ়ଶ؅ཧ  def deposit(account: Account, amount: Int): Future[Unit] = Future

    { if(account.money - amount > 0) { if(amount == 8000) Thread.sleep(1000) account.money -= amount } else { println(s"Insufficient funds (${account.money} < ${amount})") } } val account = new Account("Jack", 10000) val result1 = deposit(account, 8000) val result2 = deposit(account, 5000) Await.ready(Future.sequence(List(result1, result2)), Duration.Inf) println(s"jack's money: ${account.money}") jack's money: -3000 ϒϩοΫॲཧ ඇಉظʹAccountΦϒδΣΫτʹΞΫηε͢ΔϓϩάϥϜ
  60. Future಺Ͱͷঢ়ଶ؅ཧ  jack's money: -3000 def deposit(account: Account, amount: Int):

    Future[Unit] = Future { if(account.money - amount > 0) { if(amount == 8000) Thread.sleep(1000) account.money -= amount } else { println(s"Insufficient funds (${account.money} < ${amount})") } } val account = new Account("Jack", 10000) val result1 = deposit(account, 8000) val result2 = deposit(account, 5000) Await.ready(Future.sequence(List(result1, result2)), Duration.Inf) println(s"jack's money: ${account.money}") ॲཧ͕ϒϩοΫ͞Ε͍ͯΔؒʹɺ ผͷεϨου͔ΒAccountΦϒδΣΫτʹ ΞΫηε͞Εͯ͠·͏
  61. Future಺Ͱͷঢ়ଶ؅ཧ  Insufficient funds (5000 < 8000) jack's money: 5000

    def deposit(account: Account, amount: Int): Future[Unit] = Future { account.synchronized { if (account.money - amount > 0) { if (amount == 8000) Thread.sleep(1000) account.money -= amount } else { println(s"Insufficient funds (${account.money} < ${amount})") } } } val account = new Account("Jack", 10000) val result1 = deposit(account, 8000) val result2 = deposit(account, 5000) Await.ready(Future.sequence(List(result1, result2)), Duration.Inf) println(s"jack's money: ${account.money}") ϩοΫΛ༻͍ͯಉظ
  62. Future಺Ͱͷঢ়ଶ؅ཧ  Insufficient funds (5000 < 8000) jack's money: 5000

    def deposit(account: Account, amount: Int): Future[Unit] = Future { account.synchronized { if (account.money - amount > 0) { if (amount == 8000) Thread.sleep(1000) account.money -= amount } else { println(s"Insufficient funds (${account.money} < ${amount})") } } } val account = new Account("Jack", 10000) val result1 = deposit(account, 8000) val result2 = deposit(account, 5000) Await.ready(Future.sequence(List(result1, result2)), Duration.Inf) println(s"jack's money: ${account.money}") ϩοΫΛ༻͍ͯಉظ σουϩοΫͷةݥੑ ա৒ͳϩοΫʹΑΔύϑΥʔϚϯεͷ௿Լ
  63.  ෦෼తʹඇಉظॲཧΛ࣮૷͢Δ͚ͩͳΒɺ FutureΛ࢖͑͹࣮ݱͰ͖Δ ಺෦ʹঢ়ଶΛ࣋ͭ৔߹͸ɺಉظΛऔΔඞཁ͕ग़ͯདྷͯ͠·͏ ϩοΫΛ࢖Θͣʹ҆શʹ಺෦ঢ়ଶʹΞΫηε͍ͨ͠ Akka Actor

  64.  ࠓճ঺հ͢ΔϥΠϒϥϦ [Ҿ༻: http://spray.io/duse/#/5] ঢ়ଶΛ࣋ͬͨ ฒߦॲཧ

  65. Akka Actor  • ScalaͱJavaͷApach2ϥΠηϯεͰఏڙ͞Ε͍ͯΔOSSϥ ΠϒϥϦ • ΞΫλʔϞσϧΛద༻ͨ͠ϥΠϒϥϦ

  66. ΞΫλʔϞσϧ  ΞΫλʔϞσϧ͸ ʮ਺ඦɾ਺ઍͷϚΠΫϩϓϩηοα͔Βߏ੒͞Εɺ ݸʑʹϩʔΧϧϝϞϦΛ࣋ͪɺ ߴੑೳ௨৴ωοτϫʔΫͰ௨৴Λߦ͏ ฒྻίϯϐϡʔλ͕͍ۙকདྷొ৔͢Δͱͷ༧ଌʯ ͔Β։ൃ͞Εͨ [Ҿ༻: https://ja.wikipedia.org/wiki/

    %E3%82%A2%E3%82%AF%E3%82%BF%E3%83%BC%E3%83%A2%E3%83%87%E3%83%AB]
  67. ΞΫλʔϞσϧ  ΦϒδΣΫτࢦ޲ ΞΫλʔࢦ޲ • શͯ͸ΦϒδΣΫτ • ঢ়ଶͷΧϓηϧԽ • ৼΔ෣͍

    • ΦϒδΣΫτͷੜ੒ • ΦϒδΣΫτ΁ͷϝοηʔδ • શͯ͸ΞΫλʔ • ঢ়ଶͷΧϓηϧԽ • ৼΔ෣͍ • ΞΫλʔͷੜ੒ • ΞΫλʔ΁ͷϝοηʔδ ʮશͯͷ΋ͷ͸ΞΫλʔͰ͋Δʯͱ͍͏ࢥ૝ class AccountActor(val name: String, var money: Int) extends Actor class Account private (val name: String, var money: Int)
  68. Akka Actor  Akka Actorʹ͓͚Δฒߦॲཧͷಛ௃ • ඇಉظϝοηʔδύογϯά • ୯ҰΞΫλʔ಺Ͱͷϝοηʔδॲཧͷஞ࣍ੑ

  69. ΞΫλʔ  ܰྔϓϩηε ※ڞ༗ϝϞϦΛ࣋ͨͳ͍ͨΊɺεϨουͰ͸ͳ͘ϓϩηεͱݺͿ ΞΫλʔಉ࢜ͰϝϞϦ͸ڞ༗͠ͳ͍ AkkaͰ͸1GBͷϝϞϦʔͰɺΞΫλʔΛ270ສݸੜ੒Ͱ͖Δ (JVMͷεϨου͸1GBͰ4096ݸੜ੒Ͱ͖Δ)

  70. ඇಉظϝοηʔδύογϯά  "DUPS̎ "DUPS̍ ͦΕͧΕͷΞΫλʔ͸ϝʔϧϘοΫεΛ࣋ͪɺ ϝοηʔδΛૹΓ͋ͬͯॲཧΛߦ͏ ΞΫλʔ̍ ΞΫλʔ̎ ΞΫλʔ̏ ΞΫλʔ̐

  71. ඇಉظϝοηʔδύογϯά  ΞΫλʔؒͷϝοηʔδͷ΍ΓͱΓ͸શͯඇಉظʹߦΘΕΔ ඇಉظʹϝοηʔδΛड͚औΔ ΞΫλʔ

  72. ୯ҰΞΫλʔ಺Ͱͷ ϝοηʔδॲཧͷஞ࣍ੑ  • ୯ҰΞΫλʔʹର͢Δॲཧ͸ஞ࣍తʹͳΔͷͰɺΞΫλʔͷ಺෦ঢ়ଶʹରͯ͠ εϨουηʔϑʹͳΔ(ϩοΫ΍ಉظ͕ෆཁ) • ΞΫλʔಉ࢜͸ผϓϩηεͳͷͰɺଞͷΞΫλʔ͕಺෦ঢ়ଶʹΞΫηε͢Δ͜ͱ΋ͳ͍ • Dispatcher͕ΞΫλʔʹεϨουΛׂΓ౰ͯΔ͜ͱʹΑͬͯϝοηʔδ͕ॲཧ͞ΕΔ

    "DUPS ϝοηʔδͷॲཧ͸ஞ࣍తʹߦ͏ ΞΫλʔ
  73. Dispatcher  εϨουϓʔϧΛ͍࣋ͬͯͯɺ ΞΫλʔʹεϨουΛׂΓ౰ͯΔ͜ͱʹΑͬͯɺ ϝʔϧϘοΫε಺ͷະॲཧͷϝοηʔδΛॲཧ͢Δ •Dispatcher͸̐छྨ͋Δ •Dispatcher୯ҐͰεϨου਺΍Executorͷछྨ΋ม͑ΒΕΔ •ΞΫλʔ୯ҐͰ࢖༻͢ΔDispatcherΛม͑ΒΕΔ

  74. Dispatcher  IOό΢ϯυͳॲཧΛߦ͏Actor CPUό΢ϯυͳॲཧΛߦ͏Actor Actorͷछྨ͝ͱʹDispatcherΛ࢖͍෼͚Δ͜ͱʹΑΔ ύϑΥʔϚϯενϡʔχϯά΋Մೳ (ྫ: CPUό΢ϯυͳॲཧͷDispatcherͷεϨου਺Λଟ͘͢ΔͳͲ)

  75. Akka Actor  Dispatcher͕ ActorʹεϨουΛ ׂΓ౰ͯΔ ΞΫλʔ ͜͜ͷඇಉظॲཧ෦෼͸Akka Actor ಺෦ͰΑ͠ͳʹ΍ͬͯ͘ΕΔ

    ϓϩάϥϚʔ͸Actor͕࣮ߦ͢Δॲཧͱɺ ϝοηʔδͷૹ৴ͷ࣮૷ʹूதͰ͖Δ DispatcherʹׂΓ౰ͯΒΕͨ εϨουΛ࢖ͬͯॲཧΛ࣮ߦ ΞΫλʔ ΞΫλʔ ΞΫλʔ
  76. Akka Actor  class HelloActor extends Actor { def receive

    = { case "Hello" => println(s"World!") } } val actorSystem = ActorSystem("System") val helloActor = actorSystem.actorOf(Props[HelloActor]) helloActor ! "Hello" ΞΫλʔͷ࣮ߦ͢Δॲཧͷ࣮૷ ϝοηʔδͷૹ৴ ඇಉظϝοηʔδύογϯάͷ࣮૷ ΞΫλʔͷੜ੒
  77. ୯ҰΞΫλʔ಺Ͱͷ ϝοηʔδॲཧͷஞ࣍ੑ  ಺෦ঢ়ଶ͸อޢ͞ΕΔͨΊɺಉظॲཧΛϓϩάϥϚ͕΍Δඞཁ͕ͳ͍ money: 2000 Insufficient funds (2000 <

    5000) class AccountActor(val name: String, var money: Int) extends Actor { override def receive: Receive = { case deposit: Deposit => { if(money - deposit.amount > 0) { if(deposit.amount == 8000) Thread.sleep(1000) money -= deposit.amount println(s"money: $money") } else { println(s"Insufficient funds ($money < ${deposit.amount})") } } } } lazy val ourSystem = ActorSystem("OurSystem") val accountActor = ourSystem.actorOf(Props(classOf[AccountActor], "Jack", 10000)) accountActor ! Deposit(8000) accountActor ! Deposit(5000) ϝοηʔδ͸ඇಉظʹૹΒΕΔ͕ɺ ॲཧ͸ஞ࣍తʹߦΘΕΔ
  78. ิ଍  ϝοηʔδۦಈʹΑΔϨεϙϯγϒͳγεςϜͷ࣮ݱ Akka Actor͸ฒߦॲཧΛ࣮ݱ͢Δ͚ͩͰ͸ͳ͍ •଱ো֐ੑͳͲ •Ґஔಁաੑ •εέʔϥϏϦςΟͳͲͳͲɻɻɻ Akka͸ߋͳΔػೳΛఏڙ͢Δ(Akka RemoteɺAkka

    Cluster)
  79. FutureͱActor  ɾforࣜΛ༻͍ͨ૊Έ߹Θͤɺ݁Ռͷ߹੒ ɾঢ়ଶΛอ࣋͢ΔΦϒδΣΫτΛѻ͏ ɾঢ়ଶΛอ࣋͠ͳ͍ؔ਺Λѻ͏ ɾΞΫλʔϞσϧʹج͍ͮͨ ϝοηʔδͰͷ΍ΓͱΓ Future Akka Actor

    ࢖༻͢Δ ͜ͱ΋Մೳ
  80. Actor·ͱΊ  • Actorͷฒߦॲཧ͸ඇಉظϝοηʔδύογϯάʹΑͬͯ ࣮ݱ͞ΕΔ • ΞΫλʔϞσϧ͸ঢ়ଶʹରͯ͠εϨουηʔϑ

  81.  શͯ಺෦ͰExecutionContextΛ࢖༻͍ͯ͠Δ Future ฒྻ ίϨΫγϣϯ Akka Actor

  82. ͓඼ॻ͖  • ฒߦɾฒྻॲཧͱ͸ • ScalaͷϥΠϒϥϦʹ͍ͭͯ • ExecutionContextʹ͍ͭͯ • ·ͱΊ

  83. ExecutionContextʹ͍ͭͯ  • ExecutionContext.globalΛ࢖͑͹͍͍ͷ͔ • ࠷దͳεϨουϓʔϧͷαΠζ

  84. ExecutionContext  object Future { def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor:

    ExecutionContext): Future[T] } applyʹ౉ͯ͠ɺ಺෦ͰExecutionContext͕ඇಉظॲཧΛ࣮ߦ͍ͯ͠Δ Future Akka Actor dispatcher͸ExecutionContextΛ࢖ͬͯɺActorʹϝοηʔδΛૹ͍ͬͯΔ trait ActorContext extends ActorRefFactory { implicit def dispatcher: ExecutionContextExecutor } val defaultTaskSupport: TaskSupport = new ExecutionContextTaskSupport ฒྻ࣮ߦ͢Δtasksupportͷத਎͸ExecutionContext ฒྻίϨΫγϣϯ
  85. ExecutionContext  ॲཧʢλεΫʣΛ͍͍ײ͡ʹεϨουʹ෼഑ͯ͘͠ΕΔ εϨουϓʔϧ εϨου1 εϨου2 εϨου3 εϨου4 λεΫ1 λεΫ2

    λεΫ10 λεΫ3 λεΫ5 λεΫ8 λεΫ7 λεΫ6 λεΫ9 λεΫ4
  86. ExecutionContextͷར༻ํ๏  • ExecutionContext.global • ࣗ࡞ExecutionContext େ͖͘෼͚ͯ2छྨ͋Δ Cannot find an

    implicit ExecutionContext. You might pass [error] an (implicit ec: ExecutionContext) parameter to your method [error] or import scala.concurrent.ExecutionContext.Implicits.global.
  87. ExecutionContext.global  • scala.concurrentύοέʔδʹఆٛͯ͋͠ΔExecutionContext • ͱΓ͋͑ͣ͜ΕΛ࢖͑͹Future͕ಈ͘ • σϑΥϧτͰ͸ίΞ਺෼ͷεϨουϓʔϧΛ࡞੒͢Δ • ࣮૷͸BlockContextΛܧঝͨ͠ExecutorService

    • ฒྻίϨΫγϣϯͰσϑΥϧτͰ࢖ΘΕΔ implicit val ec = scala.concurrent.ExecutionContext.global import scala.concurrent.ExecutionContext.Implicits.global
  88. ࣗ࡞ExecutionContext  val executorService = Executors.newFixedThreadPool(4) implicit val ec =

    ExecutionContext.fromExecutorService(executorService) Future { … } ExecutorService͔ΒExecutionContextΛ࡞੒͢Δ͜ͱ͕Ͱ͖Δ ExecutorService: java.util.concurrentύοέʔδʹఆٛ͞Ε͍ͯΔ εϨουϓʔϧΛѻ͏ΦϒδΣΫτ
  89. ࣗ࡞ExecutionContext  ฒྻίϨΫγϣϯ parVector.tasksupport = new ForkJoinTaskSupport(new ForkJoinPool(4)) Akka Actor

    fork-join—dispatcher { type = Dispatcher executor = "fork-join-executor" fork-join-executor { parallelism-min = 8 parallelism-factor = 3.0 parallelism-max = 64 } throughput = 100 } thread-pool-dispatcher { type = Dispatcher executor = "thread-pool-executor" thread-pool-executor { fixed-pool-size = 32 } throughput = 1 } val helloActor = actorSystem.actorOf(Props[HelloActor].withDispatcher(“fork-join-dispatcher”)) val greeterActor = actorSystem.actorOf(Props[GreetActor].withDispatcher("thread-pool-dispatcher")) application.conf application.conf
  90. ExecutionContext.global vs ࣗ࡞ExecutionContext  • ExecutionContext.global͸γεςϜશମͷڞ༻εϨου ϓʔϧ • ϒϩοΩϯάॲཧ࣌ͷৼΔ෣͍

  91. ExecutionContext.global͸ γεςϜશମͷڞ༻εϨουϓʔϧ  ॏ͍ͨλεΫͰExecutionContext.globalͷεϨουϓʔϧΛ ઎༗ͯ͠͠·͏ͱɺଞͷ෦෼ʹӨڹ͕ग़ͯ͠·͏Մೳੑ͕͋Δ εϨου εϨου εϨου εϨου ExecutionContext.global

    λεΫ ॏ͍ͨλεΫ ×
  92. εϨουϓʔϧͷ෼ׂ  εϨου εϨου εϨου εϨου ExecutionContext.global εϨου εϨου ࣗ࡞ExecutionContext

    ϒϩοΩϯάॲཧ ϊϯϒϩοΩϯάॲཧ ϒϩοΩϯάॲཧ͸ͦΕઐ༻ͷExecutionContextΛ࡞੒ͯ͠ɺ ڞ༗ͷεϨουϓʔϧΛ઎༗͠ͳ͍Α͏ʹͨ͠΄͏͕Α͍
  93.  ExecutionContext.global͸blockingϝιου͕ݺͼग़͞Εͨ࣌ʹɺ εϨουΛࣗಈͰ૿΍͢(σϑΥϧτͰ࠷େ256εϨου·Ͱ) ϒϩοΩϯάॲཧ࣌ͷৼΔ෣͍ εϨου1 εϨου2 λεΫ1 λεΫ2 blocking εϨου

    λεΫ3 λεΫ4 blocking λεΫ5 εϨου4 λεΫ6 εϨουϓʔϧ εϨουੜ੒ εϨουੜ੒
  94. scala.concurrent.blocking  def blocking[T](body: =>T): T = BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission) ϒϩοΩϯάॲཧΛϚʔΫ͠ɺ εϨου͕ރׇ͢ΔͷΛ๷͙ώϯτΛ༩͑Δϝιου

    ExecutionContext.globalͰ͸ɺ blockingϝιουʹΑΔώϯτΛड͚औͬͯ εϨουΛ૿΍࣮͢૷͕͞Ε͍ͯΔ(BlockContextΛܧঝ)
  95. ϒϩοΩϯάॲཧ with global  blockingϝιου͕ݺ͹Εͨ࣌ʹɺ εϨουΛࣗಈͰ૿΍ͯ͘͠ΕΔʢॳظεϨου਺: 8ʣ implicit val ec

    = scala.concurrent.ExecutionContext.global val time = measure { val futures = for(_ <- 0 until 100) yield Future { blocking { Thread.sleep(1000) } } for (f <- futures) Await.ready(f, Duration.Inf) } log(s"Total time = ${time.value}") ExecutionContext.global
  96. ϒϩοΩϯάॲཧ with global  Total time = 1048 implicit val

    ec = scala.concurrent.ExecutionContext.global val time = measure { val futures = for(_ <- 0 until 100) yield Future { blocking { Thread.sleep(1000) } } for (f <- futures) Await.ready(f, Duration.Inf) } log(s"Total time = ${time.value}") blockingϝιου͕ݺ͹ΕΔͱ ExecutionContext.global͕ ࣗಈͰεϨουΛੜ੒͢Δ blockingϝιου͕ݺ͹Εͨ࣌ʹɺ εϨουΛࣗಈͰ૿΍ͯ͘͠ΕΔʢॳظεϨου਺: 8ʣ
  97. ϒϩοΩϯάॲཧ with ࣗ࡞ExecutionContext  blockingϝιου͕ݺ͹Εͯ΋ɺ εϨου͕૿͑ͳ͍ʢεϨου਺: 8ʣ val executorService =

    Executors.newWorkStealingPool(8) implicit val ec = ExecutionContext.fromExecutorService(executorService) val time = measure { val futures = for(_ <- 0 until 100) yield Future { blocking { Thread.sleep(1000) } } for(f <- futures) Await.ready(f, Duration.Inf) } println(s"Total time = ${time.value}") fromExecutorServiceΛ࢖༻
  98. ϒϩοΩϯάॲཧ with ࣗ࡞ExecutionContext  Total time = 13071 ExecutionContext.global ࢖༻࣌ΑΓ΋

    10ഒͷ࣌ؒΛཁ͢Δ blockingϝιου͕ݺ͹Εͯ΋ɺ εϨου͕૿͑ͳ͍ʢεϨου਺: 8ʣ val executorService = Executors.newWorkStealingPool(8) implicit val ec = ExecutionContext.fromExecutorService(executorService) val time = measure { val futures = for(_ <- 0 until 100) yield Future { blocking { Thread.sleep(1000) } } for(f <- futures) Await.ready(f, Duration.Inf) } println(s"Total time = ${time.value}") ϒϩοΩϯάॲཧ with ࣗ࡞ExecutionContext  fromExecutorServiceΛ࢖༻
  99. ϒϩοΩϯάॲཧ  IOͳͲͷϒϩοΩϯάॲཧ͕ExecutionContext಺ͰߦΘΕΔ৔߹͸ɺ ͦͷॲཧΛ໌ࣔతʹblockingϝιουͰғΉํ͕ྑ͍ ͨͩ͠ɺͦͷ৔߹͸BlockContextΛܧঝͨ͠ ExecutionContextΛ࢖͏ඞཁ͕͋Δ

  100. ࠷దͳεϨουϓʔϧͷαΠζ  •JVMͩͱ1εϨουͰ2Mཁ͢Δ •CPUͷՔಇ͕100%ͷ࣌ʹεϨου਺Λ૿΍ͯ͠΋ɺ ແବʹࢿݯΛ৯͍ਚ͚ͩ͘͢ Ή΍ΈʹεϨουΛ૿΍ͯ͠΋ੑೳ্͕͕Δͱ͸ݶΒͳ͍ খ͗͢͞ => CPUͷΞΠυϧ͕࣌ؒੜͯ͡ɺεϧʔϓοτ௿ԼΛಋ͘ େ͖͗͢

    => εϨου͕CPU΍ϝϞϦࢿݯΛ૪͏ɻίϯςΩετεΠονʹΑΔεϧʔϓοτ ௿ԼɺϝϞϦෆ଍Λಋ͘ খ͞ա͗ͣɺେ͖ա͗ͣ
  101. ࠷దͳεϨουϓʔϧͷαΠζ  ࣮֬ͳํ๏͸ͳ͍͕ɺܾΊΔͨΊͷཁૉ͸͋Δ •CPUͷ਺ •CPUՔಇ཰ •λεΫ଴ͪ࣌ؒͱܭࢉ࣌ؒͷൺ཰ εϨουͷ਺ = CPUͷ਺ ×

    CPUՔಇ཰ × (1 + λεΫ଴ͪ࣌ؒͱܭࢉ࣌ؒͷൺ཰) Ұྫ ࢀߟɿJavaฒߦॲཧϓϩάϥϛϯά
  102. ͓඼ॻ͖  • ฒߦɾฒྻॲཧͱ͸ • ScalaͷϥΠϒϥϦʹ͍ͭͯ • ExecutionContextʹ͍ͭͯ • ·ͱΊ

  103. ·ͱΊ  ϥΠϒϥϦ ಛ௃ Ϣʔεέʔε ฒྻίϨΫγϣϯ ίϨΫγϣϯʹର͢Δ ฒྻॲཧ ݕࡧ/બ୒/ ιʔτ/ूܭ

    'VUVSF 4DBMBΒ͍͠߹੒Մೳͳ ඇಉظॲཧ ঢ়ଶΛѻΘͳ͍ॲཧ ؔ਺ "LLB"DUPS ΞΫλʔϞσϧʹجͮ͘ ඇಉظϝοηʔδύογϯά ঢ়ଶΛѻ͏ΦϒδΣΫτ ϨεϙϯγϒͳγεςϜ
  104. ·ͱΊ  • ScalaͷϥΠϒϥϦʹ͸ͦΕͧΕಛ௃΍Ϣʔεέʔε͕͋Δ • εϨουϓʔϧͷ෼ׂ/αΠζ(ExecutionContext)Λߟྀ͢ Δ͜ͱ΋ઓུͷҰͭ