Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Ϟνϕʔγϣϯ Scala͸ฒߦɾฒྻॲཧΛߦ͏ͨΊͷϥΠϒϥϦ͕๛෋ʁ ‣ ฒߦɾฒྻॲཧΛ࣮ݱ͢ΔϥΠϒϥϦ •ඪ४ϥΠϒϥϦ •Future •ฒྻίϨΫγϣϯ •ϥΠϒϥϦ •Akka Actor •Monix Ͳ͏࢖͍෼͚Δͷ͔ Θ͔Βͳ͍

Slide 6

Slide 6 text

ScalaͷϥΠϒϥϦ͸ศར தͷ࢓૊ΈͳͲΛߟ͑ͳͯ͘΋ͱΓ͋͑ͣ؆୯ʹ࢖͑Δ Future => Future.apply͢Ε͹ผεϨουͰॲཧ͕૸Δ Akka Actor => ඇಉظϝοηʔδύογϯά͕Ͱ͖Δ ฒྻίϨΫγϣϯ => .par͢Ε͹ฒྻॲཧ͕Ͱ͖Δ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

ൃද಺༰ ࿩͢͜ͱ ࿩͞ͳ͍͜ͱ • ScalaͷฒߦɾฒྻॲཧϥΠϒϥϦ •ಛ௃ •࢓૊Έ •Ϣʔεέʔε •ϥΠϒϥϦͷࡉ͔͍࢓༷/tips •௿ϨΠϠͷ࿩(OSϨϕϧ) •ύϑΥʔϚϯενϡʔχϯά

Slide 10

Slide 10 text

ຊൃදͷΰʔϧ FutureɺAkka ActorͳͲͷฒߦɾฒྻϥΠϒϥϦͷಛ௃ɾ࢓૊ΈΛ ཧղɺ੔ཧͯ͠ΑΓ҆શͰ଎͍γεςϜ࡞Γͷॿ͚ʹͳΕ͹޾͍Ͱ͢

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

ྺ࢙తഎܠ ूੵճ࿏্ͷτϥϯδελ਺͸ʮ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]

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

ϚϧνίΞCPUΛ׆༻ͨ͠ ฒߦɾฒྻॲཧ CPU CPU1 CPU2 ҰͭͷCPU͕εϨουΛ੾Γସ͑ͳ͕Βෳ਺ͷλεΫΛ࣮ߦ͢Δ εϨουΛCPUͷίΞʹ౰ͯͯɺಉ࣌ʹλεΫΛ࣮ߦ͢Δ ฒߦॲཧ(concurrent) ฒྻॲཧ(parallel) εϨου1 εϨου2 ࣌ؒ ࣌ؒ ※ฒߦ͸ฒྻΛแؚ͢Δ

Slide 16

Slide 16 text

ฒߦɾฒྻॲཧͷ೉͠͞ • εϨουηʔϑ͕ٻΊΒΕΔ • σʔλڝ߹ʢϨʔείϯσΟγϣϯʣ • σουϩοΫ • εϨουੜ੒ɺ؅ཧͷίετ

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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 … ฒྻʹॲཧ͕࣮ߦ͞ΕΔ

Slide 28

Slide 28 text

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ͷ ࠷େͷཁૉΛٻΊΔϓϩάϥϜ

Slide 29

Slide 29 text

ฒྻॲཧ ฒྻԽͰ͖ΔλεΫΛׂΓग़ͯ͠ɺ ޮ཰Α͘෼ׂͯ͠ฒྻʹ࣮ߦ͢Δඞཁ͕͋Δ ΞϜμʔϧͷ๏ଇ ฒྻίϨΫγϣϯ͸಺෦Ͱ෼ׂ౷࣏ͷΞϓϩʔνʹج͍ͮͯίϨΫγϣϯΛ ޮ཰Α͘෼ׂͯ͠ฒྻʹԋࢉΛߦ͏

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

෼ׂ౷࣏ ߹ܭ஋ શମͷ ߹ܭ஋ ߹ܭ஋ ߹ܭ஋ ߹ܭ஋ ֤CPUͰฒྻʹ࣮ߦ "SSBZ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ sumϝιουݺͼग़͠ʹΑΔίϨΫγϣϯͷ߹ܭ஋ͷܭࢉ ArrayΛεϨου ͷ਺͚ͩ෼ׂ ͦΕͧΕͷ߹ܭ஋ Λ଍͠߹ΘͤΔ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ ෼ׂ͞Εͨ഑ྻ ͷ߹ܭ஋ͷܭࢉ

Slide 33

Slide 33 text

෼ׂ౷࣏ ෼ׂ౷࣏͸ɺ෼ׂ͞ΕͨλεΫ͕ಠཱͯ͠ ࣮ߦͰ͖Δܭࢉʹ޲͘ •ݕࡧ/બ୒ => ෼ׂ͞Εͨ୯ҐͰݕࡧ/બ୒Մೳ •ιʔτ => ෼ׂ͞ΕͨλεΫ୯ҐͰιʔτՄೳ •ूܭ => ෼ׂ͞ΕͨλεΫ୯ҐͰूܭՄೳ

Slide 34

Slide 34 text

ฒྻίϨΫγϣϯͷ࢓૊Έ 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] } ෼ׂ͞ΕͨλεΫͷԋࢉ݁ՌΛ݁߹͢Δ

Slide 35

Slide 35 text

ฒྻίϨΫγϣϯϋϚΓϙΠϯτ • ଎౓͕͕͋Δͱ͸ݶΒͳ͍ • ૝ఆ͍ͯͨ͠ܭࢉ݁ՌʹͳΒͳ͍ Ϣʔεέʔε͕ݶఆ͞ΕΔ෼ɺޡͬͨ࢖͍ํ͕ଘࡏ͢Δ

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

εϨουؒͷಉظॲཧ (σʔλڝ߹) 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ม਺Ͱ҆શͳಉظΛ ߦͬͯΧ΢ϯτΞοϓ͍ͯ͠Δ ϧʔϓॲཧͰΧ΢ϯτΞοϓ͢ΔϓϩάϥϜ

Slide 38

Slide 38 text

εϨουؒͷಉظॲཧ (σʔλڝ߹) 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") } ฒྻίϨΫγϣϯΛ࢖ͬͨ΄͏͕ ͕͔͔͍࣌ؒͬͯΔ εϨουؒͰσʔλΛਖ਼͘͠ڞ༗͢ΔͨΊʹಉظΛߦ͏ͷͰɺ ֤εϨουͰॲཧ଴͕ͪൃੜͯ͠εϧʔϓοτ͕௿Լ͢Δ

Slide 39

Slide 39 text

ฒྻίϨΫγϣϯ΁ͷม׵ίετ 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") }

Slide 40

Slide 40 text

ฒྻίϨΫγϣϯ΁ͷม׵ίετ 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ͷฒߦίϨΫγϣϯ΁ͷม׵ ʹ͔ͳΓ͕͔͔͍࣌ؒͬͯΔ

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

ฒྻίϨΫγϣϯ΁ͷม׵ίετ List Vector ParVector scala> (1 to 10000).toList.par res2: ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, … શͯͷཁૉΛίϐʔ͢ΔͷͰܭࢉίετ͕͔͔Δ ฒྻίϨΫγϣϯͷ࣮૷ Λ࣌ͨͳ͍ίϨΫγϣϯ ฒྻίϨΫγϣϯͷ࣮૷ Λ࣋ͭίϨΫγϣϯ ฒྻίϨΫγϣϯ

Slide 43

Slide 43 text

ฒྻίϨΫγϣϯͷ࣮૷Λ࣋ͭ ίϨΫγϣϯ ্هҎ֎ͷίϨΫγϣϯͷฒྻίϨΫγϣϯ΁ͷ ม׵͸͕͔͔࣌ؒΔ •Array •ArrayBuffer •Vector •mutable.HashMap •immutable.HashMap •Range •mutable.HashSet •immutable.HashSet •concurrent.TrieMap

Slide 44

Slide 44 text

૝ఆ͍ͯͨ͠ܭࢉ݁ՌʹͳΒͳ͍ • ঢ়ଶΛѻ͏ԋࢉ • ݁߹ଈ͕੒ཱ͠ͳ͍ԋࢉ

Slide 45

Slide 45 text

ঢ়ଶΛѻ͏ԋࢉ 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

Slide 46

Slide 46 text

ঢ়ଶΛѻ͏ԋࢉ ద੾ʹಉظΛऔΔͱࠓ౓͸ॲཧ଎౓͕٘ਜ਼ʹͳΔ ಺෦Ͱঢ়ଶΛѻ͏ԋࢉ͸ద੾ʹಉظΛऔΒͳ͚Ε͹ͳΒͳ͍ɹ ฒྻίϨΫγϣϯ͸֤λεΫͰ७ਮͳܭࢉΛ͢Δ΂͖

Slide 47

Slide 47 text

݁߹ଇ͕੒Γཱͨͳ͍ԋࢉ ฒྻͰ࣮ߦ͞ΕΔͷͰɺ݁߹཯͕੒Γཱͨͳ͍ԋࢉ͸ႈ౳ͳ஋ʹͳΒͳ͍ ྫ: (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

Slide 48

Slide 48 text

ฒྻCollection·ͱΊ • ฒྻίϨΫγϣϯ͸ιʔτɺݕࡧɺબ୒ɺूܭʹ޲͘ • ฒྻίϨΫγϣϯ಺ͰಉظॲཧΛߦ͏ͱࢥ͏Α͏ʹ଎͘ ͳΒͳ͍ • ฒྻίϨΫγϣϯͷ࣮૷Λ࣋ͨͳ͍ίϨΫγϣϯΛฒྻ ίϨΫγϣϯʹม׵͢Δͱࢥ͏Α͏ʹ଎͘ͳΒͳ͍ • ঢ়ଶΛѻ͏ԋࢉ΍݁߹ଇ͕੒Γཱͨͳ͍ԋࢉͰ͸ඇܾఆ ੑʹͭͳ͕ΔՄೳੑ͕͋Δ

Slide 49

Slide 49 text

ฒྻ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΁ͷ ΞΫηε

Slide 50

Slide 50 text

Future IOό΢ϯυͳॲཧʹ͓͍ͯ͸ɺ 1CPU಺Ͱෳ਺ͷεϨουΛ੾Γସ͑ͯฒߦʹ࣮ߦ͢Δํ͕ޮ཰͕ྑ͍ ※ਤ͸ཧ૝Ͱ͋Γɺ ࣮ࡍ͸OSͷεέδϡʔϥ͕εϨουΛׂΓ౰ͯΔͷͰ ͜ͷΑ͏ʹ៉ྷʹׂΓ౰ͯΒΕΔͱ͸ݶΒͳ͍ CPU1 IO଴ͪ CPU2 IO଴ͪ CPU1 εϨου1 εϨου2 IO଴ͪ CPU2 εϨου3 εϨου4 IO଴ͪ

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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 ͜͜͸ ผεϨου

Slide 54

Slide 54 text

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ͰғΉͱɺผεϨουͰඇಉظॲཧ͕૸Δ

Slide 55

Slide 55 text

Future ҰͭͷCPUͰIOॲཧͷؒʹεϨουΛ੾Γସ͑ͯଞͷ࡞ۀΛ CPUʹׂΓ౰ͯΔ͜ͱʹΑͬͯɺεϧʔϓοτ͕޲্͢Δ ※ෳ਺ͷCPU͕͋Δ৔߹͸ɺͦΕͧΕCPUͰฒྻʹ࣮ߦ͞ΕΔ͜ͱ΋͋Δ CPU CPU Future1 Future2 IO଴ͪ IO଴ͪ

Slide 56

Slide 56 text

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]

Slide 57

Slide 57 text

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)

Slide 58

Slide 58 text

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)

Slide 59

Slide 59 text

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ΦϒδΣΫτʹΞΫηε͢ΔϓϩάϥϜ

Slide 60

Slide 60 text

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ΦϒδΣΫτʹ ΞΫηε͞Εͯ͠·͏

Slide 61

Slide 61 text

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}") ϩοΫΛ༻͍ͯಉظ

Slide 62

Slide 62 text

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}") ϩοΫΛ༻͍ͯಉظ σουϩοΫͷةݥੑ ա৒ͳϩοΫʹΑΔύϑΥʔϚϯεͷ௿Լ

Slide 63

Slide 63 text

෦෼తʹඇಉظॲཧΛ࣮૷͢Δ͚ͩͳΒɺ FutureΛ࢖͑͹࣮ݱͰ͖Δ ಺෦ʹঢ়ଶΛ࣋ͭ৔߹͸ɺಉظΛऔΔඞཁ͕ग़ͯདྷͯ͠·͏ ϩοΫΛ࢖Θͣʹ҆શʹ಺෦ঢ়ଶʹΞΫηε͍ͨ͠ Akka Actor

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

ΞΫλʔϞσϧ ΦϒδΣΫτࢦ޲ ΞΫλʔࢦ޲ • શͯ͸ΦϒδΣΫτ • ঢ়ଶͷΧϓηϧԽ • ৼΔ෣͍ • ΦϒδΣΫτͷੜ੒ • ΦϒδΣΫτ΁ͷϝοηʔδ • શͯ͸ΞΫλʔ • ঢ়ଶͷΧϓηϧԽ • ৼΔ෣͍ • ΞΫλʔͷੜ੒ • ΞΫλʔ΁ͷϝοηʔδ ʮશͯͷ΋ͷ͸ΞΫλʔͰ͋Δʯͱ͍͏ࢥ૝ class AccountActor(val name: String, var money: Int) extends Actor class Account private (val name: String, var money: Int)

Slide 68

Slide 68 text

Akka Actor Akka Actorʹ͓͚Δฒߦॲཧͷಛ௃ • ඇಉظϝοηʔδύογϯά • ୯ҰΞΫλʔ಺Ͱͷϝοηʔδॲཧͷஞ࣍ੑ

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

Akka Actor Dispatcher͕ ActorʹεϨουΛ ׂΓ౰ͯΔ ΞΫλʔ ͜͜ͷඇಉظॲཧ෦෼͸Akka Actor ಺෦ͰΑ͠ͳʹ΍ͬͯ͘ΕΔ ϓϩάϥϚʔ͸Actor͕࣮ߦ͢Δॲཧͱɺ ϝοηʔδͷૹ৴ͷ࣮૷ʹूதͰ͖Δ DispatcherʹׂΓ౰ͯΒΕͨ εϨουΛ࢖ͬͯॲཧΛ࣮ߦ ΞΫλʔ ΞΫλʔ ΞΫλʔ

Slide 76

Slide 76 text

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" ΞΫλʔͷ࣮ߦ͢Δॲཧͷ࣮૷ ϝοηʔδͷૹ৴ ඇಉظϝοηʔδύογϯάͷ࣮૷ ΞΫλʔͷੜ੒

Slide 77

Slide 77 text

୯ҰΞΫλʔ಺Ͱͷ ϝοηʔδॲཧͷஞ࣍ੑ ಺෦ঢ়ଶ͸อޢ͞ΕΔͨΊɺಉظॲཧΛϓϩάϥϚ͕΍Δඞཁ͕ͳ͍ 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) ϝοηʔδ͸ඇಉظʹૹΒΕΔ͕ɺ ॲཧ͸ஞ࣍తʹߦΘΕΔ

Slide 78

Slide 78 text

ิ଍ ϝοηʔδۦಈʹΑΔϨεϙϯγϒͳγεςϜͷ࣮ݱ Akka Actor͸ฒߦॲཧΛ࣮ݱ͢Δ͚ͩͰ͸ͳ͍ •଱ো֐ੑͳͲ •Ґஔಁաੑ •εέʔϥϏϦςΟͳͲͳͲɻɻɻ Akka͸ߋͳΔػೳΛఏڙ͢Δ(Akka RemoteɺAkka Cluster)

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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 ฒྻίϨΫγϣϯ

Slide 85

Slide 85 text

ExecutionContext ॲཧʢλεΫʣΛ͍͍ײ͡ʹεϨουʹ෼഑ͯ͘͠ΕΔ εϨουϓʔϧ εϨου1 εϨου2 εϨου3 εϨου4 λεΫ1 λεΫ2 λεΫ10 λεΫ3 λεΫ5 λεΫ8 λεΫ7 λεΫ6 λεΫ9 λεΫ4

Slide 86

Slide 86 text

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.

Slide 87

Slide 87 text

ExecutionContext.global • scala.concurrentύοέʔδʹఆٛͯ͋͠ΔExecutionContext • ͱΓ͋͑ͣ͜ΕΛ࢖͑͹Future͕ಈ͘ • σϑΥϧτͰ͸ίΞ਺෼ͷεϨουϓʔϧΛ࡞੒͢Δ • ࣮૷͸BlockContextΛܧঝͨ͠ExecutorService • ฒྻίϨΫγϣϯͰσϑΥϧτͰ࢖ΘΕΔ implicit val ec = scala.concurrent.ExecutionContext.global import scala.concurrent.ExecutionContext.Implicits.global

Slide 88

Slide 88 text

ࣗ࡞ExecutionContext val executorService = Executors.newFixedThreadPool(4) implicit val ec = ExecutionContext.fromExecutorService(executorService) Future { … } ExecutorService͔ΒExecutionContextΛ࡞੒͢Δ͜ͱ͕Ͱ͖Δ ExecutorService: java.util.concurrentύοέʔδʹఆٛ͞Ε͍ͯΔ εϨουϓʔϧΛѻ͏ΦϒδΣΫτ

Slide 89

Slide 89 text

ࣗ࡞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

Slide 90

Slide 90 text

ExecutionContext.global vs ࣗ࡞ExecutionContext • ExecutionContext.global͸γεςϜશମͷڞ༻εϨου ϓʔϧ • ϒϩοΩϯάॲཧ࣌ͷৼΔ෣͍

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

εϨουϓʔϧͷ෼ׂ εϨου εϨου εϨου εϨου ExecutionContext.global εϨου εϨου ࣗ࡞ExecutionContext ϒϩοΩϯάॲཧ ϊϯϒϩοΩϯάॲཧ ϒϩοΩϯάॲཧ͸ͦΕઐ༻ͷExecutionContextΛ࡞੒ͯ͠ɺ ڞ༗ͷεϨουϓʔϧΛ઎༗͠ͳ͍Α͏ʹͨ͠΄͏͕Α͍

Slide 93

Slide 93 text

ExecutionContext.global͸blockingϝιου͕ݺͼग़͞Εͨ࣌ʹɺ εϨουΛࣗಈͰ૿΍͢(σϑΥϧτͰ࠷େ256εϨου·Ͱ) ϒϩοΩϯάॲཧ࣌ͷৼΔ෣͍ εϨου1 εϨου2 λεΫ1 λεΫ2 blocking εϨου λεΫ3 λεΫ4 blocking λεΫ5 εϨου4 λεΫ6 εϨουϓʔϧ εϨουੜ੒ εϨουੜ੒

Slide 94

Slide 94 text

scala.concurrent.blocking def blocking[T](body: =>T): T = BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission) ϒϩοΩϯάॲཧΛϚʔΫ͠ɺ εϨου͕ރׇ͢ΔͷΛ๷͙ώϯτΛ༩͑Δϝιου ExecutionContext.globalͰ͸ɺ blockingϝιουʹΑΔώϯτΛड͚औͬͯ εϨουΛ૿΍࣮͢૷͕͞Ε͍ͯΔ(BlockContextΛܧঝ)

Slide 95

Slide 95 text

ϒϩοΩϯάॲཧ 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

Slide 96

Slide 96 text

ϒϩοΩϯάॲཧ 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ʣ

Slide 97

Slide 97 text

ϒϩοΩϯάॲཧ 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Λ࢖༻

Slide 98

Slide 98 text

ϒϩοΩϯάॲཧ 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Λ࢖༻

Slide 99

Slide 99 text

ϒϩοΩϯάॲཧ IOͳͲͷϒϩοΩϯάॲཧ͕ExecutionContext಺ͰߦΘΕΔ৔߹͸ɺ ͦͷॲཧΛ໌ࣔతʹblockingϝιουͰғΉํ͕ྑ͍ ͨͩ͠ɺͦͷ৔߹͸BlockContextΛܧঝͨ͠ ExecutionContextΛ࢖͏ඞཁ͕͋Δ

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

࠷దͳεϨουϓʔϧͷαΠζ ࣮֬ͳํ๏͸ͳ͍͕ɺܾΊΔͨΊͷཁૉ͸͋Δ •CPUͷ਺ •CPUՔಇ཰ •λεΫ଴ͪ࣌ؒͱܭࢉ࣌ؒͷൺ཰ εϨουͷ਺ = CPUͷ਺ × CPUՔಇ཰ × (1 + λεΫ଴ͪ࣌ؒͱܭࢉ࣌ؒͷൺ཰) Ұྫ ࢀߟɿJavaฒߦॲཧϓϩάϥϛϯά

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

·ͱΊ ϥΠϒϥϦ ಛ௃ Ϣʔεέʔε ฒྻίϨΫγϣϯ ίϨΫγϣϯʹର͢Δ ฒྻॲཧ ݕࡧ/બ୒/ ιʔτ/ूܭ 'VUVSF 4DBMBΒ͍͠߹੒Մೳͳ ඇಉظॲཧ ঢ়ଶΛѻΘͳ͍ॲཧ ؔ਺ "LLB"DUPS ΞΫλʔϞσϧʹجͮ͘ ඇಉظϝοηʔδύογϯά ঢ়ଶΛѻ͏ΦϒδΣΫτ ϨεϙϯγϒͳγεςϜ

Slide 104

Slide 104 text

·ͱΊ • ScalaͷϥΠϒϥϦʹ͸ͦΕͧΕಛ௃΍Ϣʔεέʔε͕͋Δ • εϨουϓʔϧͷ෼ׂ/αΠζ(ExecutionContext)Λߟྀ͢ Δ͜ͱ΋ઓུͷҰͭ