Upgrade to Pro — share decks privately, control downloads, hide ads and more …

mixi tech note #05

mixi tech note #05

#技術書典10 に出典されたミクシィグループエンジニア有志による技術書です。

<< 目次 >>
1章:Haskell から Elm コードを生成する
2章:SimCLR を TensorFlow2 で実装してみた
3章:KARASTA Android版のデュエット機能の仕組み
4章:Go の interface と nil を理解する
5章:Unity DOTS 完全攻略ガイド
6章:知見を届ける技術 〜 そのアウトプット、届いてますか? 〜

<< TECH NOTE 一覧 >>
mixi tech note #01
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-01

mixi tech note #02
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-02

mixi tech note #03
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-03

mixi tech note #04
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-04

mixi tech note #05
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-05

mixi tech note #06
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-06

mixi tech note #07
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-07

MIXI TECH NOTE #08
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-08

XFLAG Tech Note Vol.01
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-01

XFLAG Tech Note vol.02
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-02

MIXI ENGINEERS

December 26, 2020
Tweet

More Decks by MIXI ENGINEERS

Other Decks in Technology

Transcript

  1. ·͕͖͑ ຊॻʮmixi tech note #05ʯ͸ɺϛΫγΟάϧʔϓʹॴଐ͢Δ༗ࢤୡʹΑͬͯࣥචɾ੍࡞͞Εͨ ٕज़ॻͰ͢ɻ࣮ࡍͷϓϩμΫτ։ൃͷݱ৔Ͱ࢖༻͞Εٕͨज़ͷ࿩΍ɺ೔ʑͷۀ຿ͷ๣Βɺݸਓతʹௐ ΂ͨ͜ͱͳͲɺࢥ͍ࢥ͍ʹࣥච͍ͯ͠·͢ɻͦͷͨΊɺ֤ষͦΕͧΕͰ׬͍݁ͯ͠Δ಺༰ʹͳ͍ͬͯ ·͢ͷͰɺ޷͖ͳষ͔Β޷͖ͳॱ൪Ͱָ͓͠Έ͍ͩ͘͞ɻ ·ͨɺຊॻ͸ɺϛΫγΟάϧʔϓʹ͋Δٕज़త஌ݟ΍ΞΠσΞΛੵۃతʹڞ༗ɾެ։͍ͯ͘͜͠ͱ ͰɺੈͷதʹΑΓྑ͍αʔϏε͕ҲΕग़͢͜ͱΛئͬͯץߦ͞Ε͍ͯ·͢ɻܝࡌ͞Ε͍ͯΔ৘ใ͸ɺ

    ࣥචऀࣗ਎ͷ؀ڥͰݕূࣥ͠ච͞Εͨ΋ͷͰ͢ͷͰɺ͝ࢀߟʹ͞ΕΔࡍ͸ɺࣗ͝਎ͷ੹೚Ͱ൑அ͠ ͝׆༻͍ͩ͘͞ɻͳ͓ɺจষදݱʹ͖ͭ·ͯ͠΋ɺࣥචऀࣗ਎ͷݴ༿Ͱ఻͑ͨ͘ɺϑϥϯΫͳදݱͱ ͳ͓ͬͯΓ·͢͜ͱ͝ཧղ͍͚ͨͩΕ͹ͱࢥ͍·͢ɻ CTO ࣨ DevRel άϧʔϓ Ұಉ ˗ຊॻʹؔ͢Δ͓໰͍߹Θͤઌ ɹ https://twitter.com/mixi_engineers ˗ϛΫγΟάϧʔϓʹ͍ͭͯ ɹ https://mixi.co.jp/ ˞ʠϛΫγΟʡ ɺ ʠmixiʡ ɺ ʠmixi ϩΰʡ ͸ɺגࣜձࣾϛΫγΟͷ঎ඪ·ͨ͸ొ࿥঎ඪͰ͢ɻ·ͨɺ֤ ࣾͷձ໊ࣾɺαʔϏεٴͼ੡඼ͷ໊শ͸ɺͦΕͧΕͷॴ༗͢Δ঎ඪ·ͨ͸ొ࿥঎ඪͰ͢ɻ iii
  2. ໨࣍ ·͕͖͑ iii ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ

    1 1.1 Haskell ͱ Elm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Haskell ͔Β Elm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 13 2.1 ࢝Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2 τϨʔχϯάϧʔϓͷ࣮૷ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.3 SimCLR ͷ࣮૷ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 ·ͱΊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 23 3.1 ࢝Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2 σϡΤοτػೳͱ͸ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.3 ίϥϘ഑৴ͷ͘͠Έ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.4 σϡΤοτͷ͘͠Έ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.5 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 33 4.1 interface ͷجૅ஌ࣝ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.2 interface ͷ಺෦දݱ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.3 nil ͷܕ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 4.4 interface ͷൺֱ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 43 5.1 ࢝Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 5.2 ϛΫγΟͰͷ Unity DOTS ΁ͷऔΓ૊Έ . . . . . . . . . . . . . . . . . . . . . . . 43 5.3 Unity DOTS ͱ͸ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.4 Entity Component System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 v
  3. ໨࣍ 5.5 C# Job System . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 5.6 Unity NetCode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.7 Unity Physics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.8 Data Flow Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 5.9 Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 5.10 Build . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 5.11 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 55 6.1 ࢝Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 6.2 ஌ݟͷΦʔϓϯԽͷ࣌୅ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 6.3 ୭΋͕௨Δ࢒೦ମݧ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 6.4 ஌ݟΛಧ͚Δٕज़ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.5 ·ͱΊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 ஶऀ঺հ 63 vi
  4. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ චऀ͸όοΫΤϯυΛ HaskellɺϑϩϯτΤϯυΛ Elm

    ͰʢझຯͷʣΞϓϦέʔγϣϯΛΑ͘࡞ ੒͠·͢ɻͦͷͱ͖ʹɺHaskell ͔Β Elm ͷίʔυΛੜ੒͢Δ͜ͱͰಉ͡Α͏ͳίʔυΛॏෳͯ͠ هड़͢Δඞཁ͕ͳ͘ͳΓ·͢ɻຊߘͰ͸ Haskell ͔Β Elm ͷίʔυΛੜ੒͢Δํ๏Λ۩ମྫΛར༻ ͯ͠঺հ͠·͢ɻ·ͨɺ͢΂ͯͷιʔείʔυ͸ GitHub ͷ matsubara0507/example-servant- elm*1 ϦϙδτϦʹ͋Γ·͢ɻ 1.1 Haskell ͱ Elm ·ͣ͸؆୯ʹ Haskell ͱ Elm ʹ͍ͭͯ঺հ͠·͢ɻHaskell ͸७ਮؔ਺ܕϓϩάϥϛϯάݴޠͰɺ ࣍ͷΑ͏ͳಛ௃͕͋Γ·͢ɻ • ڧྗͳ੩తܕ෇͚ʢܕϨϕϧϓϩάϥϛϯάͳͲ΋Մೳʣ • ڧྗͳϝλϓϩάϥϛϯάʢTemplate Haskell ͳͲʣ • ஗ԆධՁʢࣜ͸ར༻͢ΔλΠϛϯά·ͰධՁ͞Εͳ͍ʣ • ७ਮʢI/O ͷΑ͏ͳඇ७ਮͳॲཧ͸ܕͰ໌ࣔతʹผΕ͍ͯΔʣ • ڧྗͳฒߦॲཧʢܰྔεϨου΍ιϑτ΢ΣΞτϥϯβΫγϣϯϝϞϦͳͲʣ ຊߘͰॏཁʹͳΔͷ͸্ͷ 2 ͭͰ͢ɻରͯ͠ Elm ʹ͍ͭͯͰ͕͢ɺElm ΋·ͨ७ਮؔ਺ܕϓϩά ϥϛϯάݴޠͰ͢ɻͨͩ͠ɺ൚༻తͰػೳతͳ Haskell ʹରͯ͠ɺElm ͸ JavaScript ΁τϥϯεύ Πϧ͞ΕΔ Web ϑϩϯτಛԽͷϓϩάϥϛϯάݴޠͰ͢ɻͦͷͨΊඞཁ࠷௿ݶͳػೳ͚͕࣮ͩ૷͞ Ε͓ͯΓɺඇৗʹίϯύΫτͳѻ͍΍͍͢ϓϩάϥϛϯάݴޠʹͳ͍ͬͯ·͢ɻ • The Elm Architecture ͱ͍͏ಠࣗͷύλʔϯΛ࣮૷͢ΔͨΊͷݴޠ • ΠϯλϑΣʔε΍ܕΫϥεͷΑ͏ͳΞυϗοΫଟ૬ͷͨΊͷػೳ͸ͳ͍ • ύϥϝτϦοΫଟ૬ʢ͍ΘΏΔδΣωϦΫεʣ͸͋Δ • Haskell Ͱ࣮૷͞Ε͍ͯΔ *1 https://github.com/matsubara0507/example-servant-elm 1
  5. ୈ1ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.1 Haskell ͱ Elm Ϩίʔυܕ

    Haskell ͔Β Elm ͷίʔυΛੜ੒͢Δ৔߹ʹ஌͓͍ͬͯͯ΄͍͠఺ͱͯ͠ɺ2 ͭͷϨίʔυܕͷҧ ͍͕͋Γ·͢ɻ·ͣ͸ Haskell ͷϨίʔυܕΛݟͯΈ·͢ɻ Ϧετ 1.1: Haskell ͷϨίʔυܕͷྫ module Chat where data Message = Message { messageId :: Int , messageAuthor :: Text , messageBody :: Text , messageCreatedAt :: Integer -- ଟഒ௕੔਺ } data Message ͷํͷ Message ͕ܕ໊Ͱɺӈͷํͷ Message ͸஋ίϯετϥΫλͱݺ͹ΕΔ΋ ͷͰ͢ɻ஋ίϯετϥΫλΛར༻ͯ͠ Message 0 "alice" "hi" now ͱ͢Δ͜ͱͰ Message ܕ ͷ஋Λੜ੒Ͱ͖·͢ɻmessageId ΍ messageAuthor ͸ϑΟʔϧυͱݺ͹ΕΔ΋ͷͰɺ࣍ͷΑ͏ʹ ϑΟʔϧυΛར༻ͯ͠஋Λੜ੒͢Δ͜ͱ΋Ͱ͖·͢ɻ Ϧετ 1.2: Haskell ͷϑΟʔϧυͷར༻ྫ Message { messageId = 0 , messageAuthor = "alice" , messageBody = "hi" , messageCreatedAt = now } ଞʹ΋ϑΟʔϧυ͸Ϩίʔυͷ஋͔ΒҰ෦ͷ஋ΛऔΓग़͢ήολͷΑ͏ͳ໾ׂ΍ɺϨίʔυͷҰ ෦ͷ஋͚ͩΛॻ͖׵͑ͯ৽͍͠ϨίʔυΛੜ੒ͨ͠Γ͢Δͷʹ΋࢖͍·͢ɻ͜͜Ͱ஫ҙ఺ͱͯ͠ɺ ϑΟʔϧυ͸άϩʔόϧͳ໊લۭؒͷؔ਺ʹͳΔͱ͍͏ͷ͕͋Γ·͢ɻͨͱ͑͹ɺmessageId Ͱ͸ ͳ͘ id ͱ͍͏ϑΟʔϧυ໊Λ෇͚Δͱ͠·͢ʢΉ͠Ζཧ૝తʹ͸ͬͪ͜Ͱ͢Ͷʣ ɻͦͷ৔߹͸࣍ͷ Α͏ͳΤϥʔ͕ग़ͯ͠·͍·͢ɻ src/Chat.hs:38:5: error: Ambiguous occurrence ʞidʟ It could refer to either ʞPrelude.idʟ, imported from ʞPreludeʟ at src/Chat.hs:5:8-11 2
  6. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.1 Haskell ͱ

    Elm (and originally defined in ʞGHC.Baseʟ) or ʞChat.idʟ, defined at src/Chat.hs:21:7 | 38 | { id = 0 | ^^ ͜Ε͸ id ؔ਺͕ෳ਺ఆٛ͞Ε͍ͯΔͷͰɺͲͬͪΛ࢖͏΂͖͔Θ͔Βͳ͍ͱ͍͏ΤϥʔͰ ͢ɻHaskell ʹ͸૊ࠐΈ id ͱ͍͏ؔ਺͕ఆٛ͞Ε͍ͯ·͢ɻલड़ͨ͠ͱ͓ΓɺϑΟʔϧυ΋ؔ ਺ͱͯࣗ͠ಈͰఆٛ͞ΕΔͷͰɺ͜ΕͰෳ਺ఆٛ͞Εͨ͜ͱʹͳΔͷͰ͢ɻͦͷͨΊɺHaskeller ͷଟ͘͸ϑΟʔϧυ໊ʹܕ໊ͷ઀಄ࣙΛ෇͚ͯ͜ΕΛճආ͍ͯ͠·͢ɻ༨ஊͰ͕͢ɺ͜ͷ໰୊͸ OverloadedRecordFields *2 ͱ͍͏໊લͰݹ͔Βٞ࿦͕͞Ε͓ͯΓɺղܾʹ޲͚ͯগͣͭ͠ GHC ݴ ޠ֦ுΛ૿΍͍ͯ͠·͢ɻ ࣍ʹ Elm ͷϨίʔυܕʹ͍ͭͯ঺հ͠·͢ɻElm Ͱ Message ܕΛهड़͢Δ৔߹͸࣍ͷΑ͏ʹॻ ͚·͢ɻ Ϧετ 1.3: Elm ͷϨίʔυܕͷྫ module Chat exposing (Message) type alias Message = { id: Int , author: String , body: String , createdAt: Int -- Elmʹଟഒ௕੔਺ܕ͸ͳ͍ } Elm ͸ type alias ͱ͍͏༧໿ޠͰϨίʔυܕΛఆٛ͠·͢ɻ·ͨɺHaskell ʹ͋ͬͨ஋ίϯε τϥΫλΛ໌ࣔ͢Δඞཁ͸͋Γ·ͤΜʢMessage 0 "alice" "hi" now ͱ͍͏ॻ͖ํ͸Ͱ͖·͢ʣ ɻ ϑΟʔϧυ໊Λ id ΍ author ʹ͍ͯ͠Δͷ͸ɺHaskell ʹ͋ͬͨϨίʔυ໰୊͸ Elm ʹͳ͍͔Β Ͱ͢ʢત·͍͠ʣ ɻ༨ஊͰ͕͢ɺElm ͸ .id ΍ .author ͷΑ͏ʹɺυοτ + ϑΟʔϧυ໊͕ήολ ͷΑ͏ͳৼΔ෣͍Λ͢Δؔ਺ʹͳΓ·͢ɻ Template Haskell Template Haskell ͸ Haskell ͷڧྗͳϝλϓϩάϥϛϯάػೳͷҰͭͰ͢ɻίϯύΠϧ࣌ʹ֎෦ ϑΝΠϧΛಡΈࠐΜͰຒΊࠐΜͩΓɺίϯύΠϧ࣌ͷ Haskell ίʔυͷ৘ใΛར༻ͯ͠ܕΫϥεʢΠ ϯλϑΣʔεͷΑ͏ͳ΋ͷʣͷ࣮૷Λఆٛͨ͠ΓͰ͖·͢ɻࠓճ͸ޙऀͷํΛར༻͠·͢ɻͨͱ͑͹ Message ܕͷίϯύΠϧ࣌ͷ৘ใΛऔಘͯ͠Έ·͢ɻ *2 https://gitlab.haskell.org/ghc/ghc/-/wikis/records/overloaded-record-fields 3
  7. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.1 Haskell ͱ

    Elm (ghci)> :!cat src/Hoge.hs {-# LANGUAGE TemplateHaskell #-} module Hoge where import Chat import Language.Haskell.TH hoge = $(do info <- reify ’’Message runIO $ print info return $ ListE []) (ghci)> :l src/Hoge.hs [1 of 2] Compiling Chat ( src/Chat.hs, interpreted ) [2 of 2] Compiling Hoge ( src/Hoge.hs, interpreted ) TyConI ( DataD [] Chat.Message [] Nothing [ RecC Chat.Message [ ( Chat.messageId , Bang NoSourceUnpackedness NoSourceStrictness , ConT GHC.Types.Int ) , ( Chat.messageAuthor , Bang NoSourceUnpackedness NoSourceStrictness , ConT Data.Text.Internal.Text ) , ( Chat.messageBody , Bang NoSourceUnpackedness NoSourceStrictness , ConT Data.Text.Internal.Text ) , ( Chat.messageCreatedAt , Bang NoSourceUnpackedness NoSourceStrictness , ConT GHC.Types.Integer ) ] ] []) Ok, two modules loaded. TyConI Ҏ߱ͷ෦෼͸ಡΈ΍͍͢Α͏ʹద౰ʹվߦ͍ͯ͠·͢ɻ৘ใΛऔಘ͢Δؔ਺ reify *3ʹ ͸ Name ܕͷ஋Λ༩͑·͢ɻName ܕ͸ Haskell ίʔυ্Ͱར༻͞ΕΔ͋ΒΏΔ໊લɺܕ໊΍ؔ਺໊ ͳͲΛදݱͨ͠ܕͰ͢ɻܕ໊͸ ’’Message ͷΑ͏ʹγϯάϧΫΦʔτΛ 2 ͭલʹ෇͚Δ͜ͱͰ೚ҙ ͷܕΛ Name ܕͷ஋ʹͰ͖·͢ɻࡉ͔͘͸ׂѪ͠·͕͢ɺChat.messageId ͸ϑΟʔϧυؔ਺ͷ Na me ܕͷ஋Ͱ͢ɻܕͷ৘ใͱͯ͠ɺϑΟʔϧυ໊΍ϑΟʔϧυͷܕͳͲ͕औΕ͍ͯΔ͜ͱ͕Θ͔Δͱ ࢥ͍·͢ɻ ༨ஊͰ͕͢ɺTemplate Haskell ͱ͸ҧ͍ɺ࣮ߦ࣌ʹܕͷ৘ใΛʢগ͚ͩ͠ʣऔಘ͢Δํ๏΋͋Γ *3 https://hackage.haskell.org/package/template-haskell-2.16.0.0/docs/Language-Haskell-TH.html# v:reify 4
  8. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm ·͢ɻTypeable ͱݺ͹ΕΔ΋ͷͰ࣍ͷΑ͏ʹར༻Ͱ͖·͢ɻ (ghci)> import Data.Typeable (typeOf) (ghci)> typeOf (undefined :: Message) Message (ghci)> typeOf True Bool (ghci)> typeOf "abc" [Char] ͜ΕΛར༻ͯ͠ɺಈతͳܕΩϟετΛఆٛͨ͠ΓͰ͖·͢ɻ αϯϓϧͷߏ੒ ۩ମྫͱͯ͠ར༻͢Δαϯϓϧ͸΋ͷ͘͢͝؆қతͳνϟοτϖʔδΛߟ͑·͢ɻϢʔβʔͳͲͷ ৘ใ͸ͳ͘ɺͨͩϙετ͞ΕͨϝοηʔδΛཷΊࠐΜͰදࣔ͢Δ͚ͩͰ͢ɻ ਤ 1.1: ΋ͷ͘͢͝؆қతͳνϟοτϖʔδ ϝοηʔδΛͲ͜ʹͲ͏อଘ͢Δ͔͸ຊ࣭త͡Όͳ͍ͷͰׂѪ͠·͢ɻWeb ϑϨʔϜϫʔΫʹ͸ Servant *4ͱ͍͏ͷΛར༻͠·͢ɻ͜ͷϑϨʔϜϫʔΫʹ͸ʮAPI ΛܕͰදݱ͢Δʯͱ͍͏ಛ௃͕͋ Γ·͢ɻAPI ͷܕʹରͯ͠ΞυϗοΫଟ૬ʢܕΫϥεʣΛ༻ҙ͢Δ͜ͱͰɺܕ͔Β API ͷ৘ใΛग़ ྗ͠ɺͦΕΛ֤ݴޠͷ API ݺͼग़ؔ͠਺΁ม׵Ͱ͖·͢ɻ 1.2 Haskell ͔Β Elm ͔͜͜Β͕ຊ୊Ͱ͢ɻ·ͣ͸ Haskell Ͱఆٛͨ͠ܕΛ Elm ͱͯ͠ੜ੒͠·͢ɻ *4 https://www.servant.dev 5
  9. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm elm-bridge ͜Εʹ͸ elm-bridge *5ͱ͍͏ύοέʔδΛར༻͠·͢ɻར༻͢Δόʔδϣϯ͸ 0.6.1 Ͱ͢ɻ elm-bridge ʹ͸ Elm ͷܕఆٛΛදͨ͠ ETypeDef ܕ͕͋Γ·͢ɻ Ϧετ 1.4: ETypeDef ͷఆٛ data ETypeDef = ETypeAlias EAlias -- Ϩίʔυܕʢ௚ੵܕʣ | ETypePrimAlias EPrimAlias -- ී௨ͷܕΤΠϦΞε | ETypeSum ESum -- ௚࿨ܕ data EAlias = EAlias { ea_name :: ETypeName, ea_fields :: [(String, EType)] } data EPrimAlias = EPrimAlias { epa_name :: ETypeName, epa_type :: EType } data ESum = ESum { es_name :: ETypeName, es_constructors :: [SumTypeConstructor] } -- ‘type Hoge = A Int | B { hoge : Int }‘ ͷ ‘|‘ ͰผΕͯΔ෦෼ data SumTypeConstructor = STC { _stcName :: String, _stcFields :: SumTypeFields } data SumTypeFields = Anonymous [EType] -- ‘A Int‘ ͷΑ͏ͳέʔε | Named [(String, EType)] -- ‘B { hoge : Int }‘ ͷΑ͏ͳέʔε -- Elm ͷܕ໊ data EType = ETyVar ETVar -- ܕม਺ | ETyCon ETCon -- ۩ମܕʢਖ਼֬ʹ͸ܕίϯετϥΫλʣ | ETyApp EType EType -- Maybe Int ͷΑ͏ͳܕ͕ద༻͞ΕΔέʔε | ETyTuple Int -- λϓϧɺ(Int, Bool) ͳΒ ETyApp (ETyTuple 2) ... ͬͯײ͡ newtype ETCon = ETCon { tc_name :: String } data ETypeName = ETypeName { et_name :: String, et_args :: [ETVar] } newtype ETVar = ETVar { tv_name :: String } ͦͯ͠ɺ೚ҙͷܕ͔Β ETypeDef ܕ΁ͷม׵ؔ਺Λఆٛ͢ΔͨΊͷܕΫϥεͱͯ͠ IsElmDefi nition ͕͋Γ·͢ɻͭ·ΓɺHaskell ͷܕ͔Β Elm ͷܕΛੜ੒͍ͨ͠৔߹͸ɺHaskell ͷܕʹର ͯ͠ IsElmDefinition ܕΫϥεͷΠϯελϯεΛఆٛͯ͋͛͠Ε͹ྑ͍ͷͰ͢ɻ͞Βʹɺ͜ΕΛ Template Haskell Λར༻ͯࣗ͠ಈಋग़͢Δํ๏͕ఏڙ͞Ε͍ͯ·͢ɻࠓճ͸ͦΕΛ࢖͍·͢ɻ Ϧετ 1.5: IsElmDefinition ܕΫϥεͷ Message ܕͷ࣮૷ {-# LANGUAGE TemplateHaskell #-} module Chat where import qualified Elm.Derive as Elm data Message = Message *5 https://hackage.haskell.org/package/elm-bridge-0.6.1 6
  10. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm { messageId :: Int , messageAuthor :: Text , messageBody :: Text , messageCreatedAt :: UTCTime } -- ͚ͩ͜͜௥ه Elm.deriveElmDef (Elm.defaultOptionsDropLower $ length "message") ’’Message Elm Ͱ͸ messageId ͷ઀಄ࣙ෦෼Λ࡟Γ͍ͨͷͰ defaultOptionsDropLower ͱ͍͏ͷΛར༻ ͍ͯ͠·͢ɻ͜ΕͰ͋ͱ͸࣍ͷΑ͏ͳ main ؔ਺Λఆ࣮ٛͯ͠ߦ͢Δ͚ͩͰ͢ɻ Ϧετ 1.6: Elm ͷܕఆٛΛੜ੒͢Δ Main.hs module Main where import qualified Chat import Data.Proxy import Elm.Module (DefineElm (DefineElm), makeElmModule) main :: IO () main = putStrLn $ makeElmModule "Generated.Chat" -- Ϟδϡʔϧ໊ [ DefineElm (Proxy :: Proxy Chat.Message) ] ࣍ͷΑ͏ͳ Elm ίʔυΛඪ४ग़ྗ͠·͢ɻ Ϧετ 1.7: Haskell ͔Βੜ੒͞Εͨ Elm ίʔυ module Generated.Chat exposing(..) import Json.Decode import Json.Encode exposing (Value) -- The following module comes from bartavelle/json-helpers import Json.Helpers exposing (..) import Dict exposing (Dict) import Set exposing (Set) type alias Message = { id: Int , author: String , body: String , createdAt: Int } jsonDecMessage : Json.Decode.Decoder ( Message ) 7
  11. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm jsonDecMessage = Json.Decode.succeed (\pid pauthor pbody pcreatedAt -> {id = pid, author = pauthor, body = pbody, createdAt = pcreatedAt}) |> required "id" (Json.Decode.int) |> required "author" (Json.Decode.string) |> required "body" (Json.Decode.string) |> required "createdAt" (Json.Decode.int) jsonEncMessage : Message -> Value jsonEncMessage val = Json.Encode.object [ ("id", Json.Encode.int val.id) , ("author", Json.Encode.string val.author) , ("body", Json.Encode.string val.body) , ("createdAt", Json.Encode.int val.createdAt) ] Haskell ͔Βੜ੒͢Δେ͖ͳར఺ͱͯ͠ɺJSON ͷΤϯίʔμɾσίʔμ΋ੜ੒Ͱ͖Δ఺͕͋Γ· ͢ɻElm ʹ͸ Haskell ͷΑ͏ͳڧྗͳϝλϓϩάϥϛϯά͕ͳ͍ͨΊɺຊདྷ͸ JSON ͷΤϯίʔ μɾσίʔμΛखॻ͖͢Δඞཁ͕͋Γ·͢ɻ༨ஊͰ͕͢ɺderiveElmDef ͷ୅ΘΓʹ deriveBoth Λར༻͢Δ͜ͱͰɺHaskell ଆͷ JSON ͷΤϯίʔμɾσίʔμΛ Template Haskell Ͱੜ੒ͯ͘͠ Ε·͢ɻ servant-elm ࠷ޙʹ Servant Ͱهड़ͨ͠ API ͷܕ͔Β Elm Ͱར༻͢Δ API ΛݺͿؔ਺Λੜ੒͠·͢ɻલड़ ͨ͠ͱ͓ΓɺServant Λར༻͢Δ͜ͱͰܕͰ API ΛදݱͰ͖·͢ɻࠓճ͸࣍ͷΑ͏ͳܕΛఆٛ͠· ͨ͠ɻ Ϧετ 1.8: Servant Ͱఆٛͨ͠ API ܕ {-# LANGUAGE DataKinds, TemplateHaskell, TypeOperators #-} module Chat where import qualified Elm.Derive as Elm import Servant.API ((:<|>) (..), (:>), Get, JSON, Post, ReqBody) type API = "messages" :> Get ’[JSON] [Message] :<|> "messages" :> ReqBody ’[JSON] PostMessage :> Post ’[JSON] () data Message = ... -- ׂѪ data PostMessage = PostMessage { postMessageAuthor :: Text , postMessageBody :: Text } Elm.deriveBoth (Elm.defaultOptionsDropLower $ length "postMessage") ’’PostMessage 8
  12. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm ͢΂ͯͷϝοηʔδΛฦ͢ GET API ͱϝοηʔδΛૹ৴͢Δ POST API Λఆ͍ٛͯ͠·͢ɻP ostMessage ܕ͸ POST ༻ͷܕͰ͢ʢͦΜ·Μ·ʣ ɻ Servant ͸ servant-foreign ύοέʔδ*6ʹ͋Δ HasForeign ܕΫϥεΛར༻ͯ͠ɺ Ϧετ 1.8 ͷ Α͏ͳ API Λදͨ͠ܕ͔ΒϦΫΤετΛදݱͨ͠ Req ftype ܕΛฦؔ͢਺ΛఆٛͰ͖·͢ɻ͜ͷ ϦΫΤετΛද͢ܕͷ஋Λར༻ͯ͠ม׵ઌͷϓϩάϥϛϯάݴޠͷίʔυΛੜ੒͠·͢ɻ͜͜Ͱ fty pe ܕม਺͸ HasForeignType ܕΫϥεͷΠϯελϯεͰ͋Δඞཁ͕͋Γɺม׵ઌͷϓϩάϥϛϯά ݴޠͷܕΛද͢ܕΛҙຯ͍ͯ͠·͢ɻͭ·Γɺࠓճͷ৔߹͸ EType Ͱ͢ͶɻElm ͷ HasForeignTy pe ܕΫϥεͷΠϯελϯεΛఆ͍ٛͯ͠Δͷ͕ servant-elm ύοέʔδ*7Ͱ͢ɻࠓճ͸όʔδϣϯ 0.7.2 Λར༻͠·͢ɻ Ϧετ 1.9: Elm ͷ HasForeignType ܕΫϥεͷΠϯελϯε data LangElm instance (Typeable a) => HasForeignType LangElm EType a where typeFor _ _ _ = toElmType (Proxy :: Proxy a) toElmType ͸ elm-bridge ʹఆٛ͞Ε͓ͯΓɺTypeable a => Proxy a -> EType ͱ͍͏ܕͰ ͢ɻTypeable ͸ Haskell ͷ͢΂ͯͷܕʹରͯ͠ඪ४Ͱ࣮૷͞Ε͍ͯΔܕΫϥεͰ͢ͷͰɺಛʹ৽͠ ͘Կ͔Λఆٛ͢Δඞཁ͸͋Γ·ͤΜɻ͋ͱ͸ servant-elm ʹ͋Δ Elm ίʔυੜ੒༻ͷؔ਺Λར༻͠ ͯɺ࣍ͷΑ͏ʹ main ؔ਺Λهड़࣮ͯ͠ߦ͢Δ͚ͩͰ͢ɻ Ϧετ 1.10: Elm ͷܕఆٛͱ API Λݺͼग़ؔ͢਺Λੜ੒͢Δ Main.hs {-# LANGUAGE DataKinds, TypeOperators, OverloadedStrings #-} module Main where import qualified Chat import Servant.API ((:>)) import Servant.Elm main :: IO () main = generateElmModuleWith defElmOptions ["Generated", "Chat"] -- Ϟδϡʔϧ໊ defElmImports "elm-src" -- ੜ੒͢ΔϑΝΠϧͷஔ͖৔ॴ [ DefineElm (Proxy :: Proxy Chat.Message) , DefineElm (Proxy :: Proxy Chat.PostMessage) ] (Proxy :: Proxy ("api" :> Chat.API)) *6 https://hackage.haskell.org/package/servant-foreign *7 https://hackage.haskell.org/package/servant-elm-0.7.2 9
  13. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.2 Haskell ͔Β

    Elm Ϧετ 1.6 ͷͱ͖͸ඪ४ग़ྗʹग़ྗ͢Δ͚ͩͰ͕ͨ͠ɺͬͪ͜͸ϑΝΠϧʹग़ྗ͠·͢ɻͦͯ͠ɺ ࣍ͷΑ͏ͳ Elm ίʔυ͕ੜ੒͞Ε·͢ɻ Ϧετ 1.11: Haskell ͔Βੜ੒͞Εͨ Elm ίʔυ module Generated.Chat exposing(..) ... -- ׂѪ getApiMessages : (Result Http.Error ((List Message)) -> msg) -> Cmd msg getApiMessages toMsg = let params = List.filterMap identity (List.concat []) in Http.request { method = "GET" , headers = [] , url = Url.Builder.crossOrigin "" [ "api", "messages" ] params , body = Http.emptyBody , expect = Http.expectJson toMsg (Json.Decode.list (jsonDecMessage)) , timeout = Nothing , tracker = Nothing } postApiMessages : PostMessage -> (Result Http.Error (()) -> msg) -> Cmd msg postApiMessages body toMsg = let params = List.filterMap identity (List.concat []) in Http.request { method = "POST" , headers = [] , url = Url.Builder.crossOrigin "" [ "api", "messages" ] params , body = Http.jsonBody (jsonEncPostMessage body) , expect = Http.expectString (\x -> case x of Err e -> toMsg (Err e) Ok _ -> toMsg (Ok ())) , timeout = Nothing , tracker = Nothing } ؔ਺໊͸ API ͷύεͱ HTTP ϝιου͔Βੜ੒͞Ε͍ͯ·͢ɻ༨ஊͰ͕͢ɺ࢒೦ͳ͕Βݱঢ়Ͱ ͸ timeout ΍ tracker ͳͲͷࡉ͔͍ઃఆ͸Ͱ͖·ͤΜɻ 10
  14. ୈ 1 ষ Haskell ͔Β Elm ίʔυΛੜ੒͢Δ 1.3 ऴΘΓʹ 1.3

    ऴΘΓʹ elm-bridge ͱ servant-elm ͷ͓͔͛ͰɺElm + Haskell ͱ͍͏૊Έ߹Θͤͷ Web ΞϓϦέʔγϣ ϯΛ؆୯ʹ࡞Δ͜ͱ͕Ͱ͖·͢ɻ͔͠΋ɺڧྗͳϝλϓϩάϥϛϯάͷ͓͔͛Ͱ Haskell ଆͰॻ͘΂ ͖ίʔυ͸΄ΜͷͪΐͬͱͰ͢ɻ͍͢͝Ͱ͢ΑͶ Haskellʂ 11
  15. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠ Έͨ 2.1 ࢝Ίʹ

    ࠷ۙͰ͸ڭࢣͳ͠ͷਂ૚ֶश͕ൃల͖͓ͯͯ͠ΓɺݚڀྖҬ͚ͩͰͳ͘ɺࣄۀΛల։͢ΔاۀͰ΋ બ୒ࢶʹͳ͖͍ͬͯͯΔͷͰ͸ͳ͍͔ͱࢥ͍·͢ɻैདྷͰ͋Ε͹ɺࣄۀʹ"͍ΘΏΔ AI"Λ׆༻͠Α ͏ͱࢥͬͨ࣌ʹɺେྔͷΞϊςʔγϣϯ͞Εͨσʔλ͕ඞཁͰ͕ͨ͠ɺڭࢣͳ͠Ͱ΋Ͱ͖Δ͜ͱ͕૿ ͖͑ͯͨͨΊɺاۀͰ΋׆༻ͷνϟϯε͕޿͕͖͍ͬͯͯΔͱࢥ͍·͢ɻචऀࣗ਎ɺݱࡏ͸ۀ຿Ͱڭ ࢣͳ͠ͷΞϓϩʔνΛࢼ͍ͯ͠·͢ɻ ࠓճ୊ࡐͱͯ͠ѻ͏ͷ͸ɺͦͷதͰ΋ SimCLR ͱ͍͏ख๏Ͱɺ͜Ε͸ Google ͕ 2020 ೥ 2 ݄ʹॳ ߘΛग़ͨ͠࿦จʮA Simple Framework for Contrastive Learning of Visual Representationsʯ *1ͷ ख๏ͰɺSelf-Supervised ͳදݱֶशͷ State-of-The-ArtʢSoTAʣͱͯ͠༗໊ʹͳ͍ͬͯ·͢ɻ ਤ 2.1: ࿦จʮA Simple Framework for Contrastive Learning of Visual Representationsʯͷਤ 1,2 ͦͷ໊ͷ௨Γɺ൚༻తͳࢹ֮දݱΛ֫ಘ͢ΔͨΊͷϑϨʔϜϫʔΫͱͳ͓ͬͯΓɺಛʹɺSelf- *1 https://arxiv.org/abs/2002.05709 13
  16. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.1 ࢝Ίʹ Supervised

    Learning Ͱڭࢣ͋Γֶशʹ΋ඖఢ͢ΔੑೳΛൃش͍ͯ͠Δͱ͍͏ڧྗͳख๏Ͱ͢ɻ͜͏ ͍ͬͨཧ༝͔Βɺ΄͔ͷݚڀ։ൃͷࣄྫͰ΋બ୒ࢶʹ্͕ΔՄೳੑͷߴ͍ख๏ʹͳΔͷͰ͸ͳ͍͔ͱ ߟ͍͑ͯ·͢ɻ SimCLR ͷ࣮૷͸ɺGoogle Research ͕ެ։͍ͯ͠Δެ࣮ࣜ૷ͷ΄͔ɺPyTorch ΍ TensorFlow2 ͳͲɺ ͞·͟·ͳ࣮૷ྫ͕ެ։͞Ε͍ͯ·͢ɻͨͩ͠ɺ ެ࣮ࣜ૷͸ػೳͯΜ͜੝Γͷɺ ͔ͳΓϘϦϡʔ Ϝ͕͋Δෳࡶͳ࣮૷ʹͳ͓ͬͯΓɺݚڀ։ൃͰͷվมɾվྑΛՃ͍͑ͯ͘͜ͱ͕ൺֱత೉͍͠ঢ়ଶʹ ͳ͍ͬͯ·͢ɻҰํɺඇެࣜͷ࣮૷ྫ͸ɺMinimal ͳ࣮૷ʹͳ͍ͬͯ·͕͢ɺ෼ࢄֶश΁ͷରԠ͕ߟ ͑ΒΕ͍ͯͳ͍ঢ়ଶʹͳ͍ͬͯ·͢ɻ ࣮͸ SimCLR ʹ͓͍ͯ͸෼ࢄֶश΁ͷରԠ͸ඇৗʹॏཁʹͳΓ·͢ɻͱ͍͏ͷ΋ɺSimCLR ͸ Contrastive Learning Ͱ͋ΓɺόοναΠζ୯ҐͰͦͷֶशͷεςοϓ͕࣮ߦ͞Ε·͢ɻͭ·Γɺ όοναΠζΛେ͖͘͢Δ΄Ͳ Contrastive Learning ͷωΨςΟϒαϯϓϧ͕૿͑Δ͜ͱʹͳΓ· ͢ɻͦͷͨΊɺਫ਼౓Λ্͛ΔͨΊʹ͸ڊେͳόοναΠζͰֶश͢Δඞཁ͕͋Γɺ࣮ࡍɺ࿦จ಺Ͱ΋ όοναΠζΛม࣮͑ͨݧͰਫ਼౓΁ͷӨڹΛ͍ࣔͯ͠·͢ɻ ਤ 2.2: ࿦จʮA Simple Framework for Contrastive Learning of Visual Representationsʯͷਤ 9 ͜͏͍ͬͨཧ༝ͰɺڊେͳόοναΠζͰͷֶशΛՄೳʹ͢ΔͨΊʹ෼ࢄֶशͷ࣮૷͕ඞཁʹͳΓ ·͢ɻ اۀͷݚڀ։ൃऀʹͱͬͯ͸ɺՄಡੑ͕ߴ͘ɺ௥Ճ։ൃͷ͠΍͍͢ Minimal ͳ࣮૷Ͱ͋Δ͜ͱͱɺ ෼ࢄֶशʹͪΌΜͱରԠͨ͠ެ։࣮૷͕͋Δͷ͕๬·͍͠ͱࢥͬͨͷͰ͕͢ɺͦ͏͍࣮ͬͨ૷͕ͳ ͔ͬͨͨΊɺࣗ෼Ͱ࣮૷͠Α͏ͱࢥ͍ࢸͬͨͷ͕ࠓճͷܦҢʹͳΓ·͢ɻ ͳΔ΂͘؆୯ʹࢼͤͯɺ࣮຿ͷཁ݅Λຬͨ͢Α͏ʹ࣮૷͠·ͨ͠ͷͰɺͦͷ঺հΛ͍͖ͯ͠·͢ɻ ·ͨɺ߹Θͤͯ TensorFlow2 ͷ࣮૷ύλʔϯͱͯ͠ɺtf.keras.Model ʹد࣮ͤͨ૷͕༏Ε͍ͯΔ ͱࢥͬͨͷͰͦͷઆ໌΋͍ܰͯ͘͜͠͏ͱࢥ͍·͢ɻ 14
  17. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.2 τϨʔχϯάϧʔϓͷ࣮૷ 2.2

    τϨʔχϯάϧʔϓͷ࣮૷ TensorFlow ʹ͸ಉ͡ख๏ͷ࣮૷Λߦ͏ʹ΋͞·͟·ͳ࣮૷ํ๏͕͋Γ·͢ɻࠓճ͸ɺ࢖͍·Θ͠ ΍͍͢ Minimal ͳ࣮૷Λ৺ֻ͚͍ͯΔͨΊɺtf.keras.Model ͷΤίγεςϜΛे෼ʹ׆͔࣮ͨ͠ ૷Λߦ͍·͢ɻ tf.keras.Model.fit ͸ɺTensorFlow Ͱඪ४࣮૷͞Εͨख๏Ͱ͋Ε͹ɺࣗ෼ͰτϨʔχϯάϧʔ ϓΛ࣮૷͢Δඞཁ͕ͳ͘ɺҎԼͷΑ͏ʹίϯύΠϧ͢Δ͚ͩͰ࢖༻Ͱ͖ΔͨΊɺ؆୯ͳख๏΍࣮ݧΛ ߦ͏ࡍʹΑ͘࢖ΘΕ͍ͯ·͢ɻ tf.keras.Model.fit ͷ৔߹ͷ࣮૷ model = build_model(~) model.compile(loss=my_loss_func, optimizer=my_optimizer, metrics=["accuracy"]) model.fit(~) ΑΓෳࡶͳτϨʔχϯάϧʔϓΛ૊Ήඞཁ͕͋Δ৔߹͸ɺcustom training roops*2Ͱ࣮૷͞Ε ͍ͯΔέʔε͕ଟ͍Ͱ͢ɻ custom training roops ͷ࣮૷ྫ @tf.function def train_step(x, y): with tf.GradientTape() as tape: logits = model(x, training=True) loss_value = loss_fn(y, logits) # Add any extra losses created during the forward pass. loss_value += sum(model.losses) grads = tape.gradient(loss_value, model.trainable_weights) optimizer.apply_gradients(zip(grads, model.trainable_weights)) train_acc_metric.update_state(y, logits) return loss_value for epoch in range(epochs): print("\nStart of epoch %d" % (epoch,)) start_time = time.time() # Iterate over the batches of the dataset. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset): loss_value = train_step(x_batch_train, y_batch_train) # Log every 200 batches. *2 https://www.tensorflow.org/guide/keras/writing_a_training_loop_from_scratch 15
  18. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.2 τϨʔχϯάϧʔϓͷ࣮૷ if

    step % 200 == 0: print( "Training loss (for one batch) at step %d: %.4f" % (step, float(loss_value)) ) print("Seen so far: %d samples" % ((step + 1) * 64)) # Display metrics at the end of each epoch. train_acc = train_acc_metric.result() print("Training acc over epoch: %.4f" % (float(train_acc),)) # Reset training metrics at the end of each epoch train_acc_metric.reset_states() # Run a validation loop at the end of each epoch. for x_batch_val, y_batch_val in val_dataset: test_step(x_batch_val, y_batch_val) val_acc = val_acc_metric.result() val_acc_metric.reset_states() print("Validation acc: %.4f" % (float(val_acc),)) print("Time taken: %.2fs" % (time.time() - start_time)) ͔͠͠ɺtf.keras.Model.fit ΋ɺ࣮͸಺෦Ͱݺͼग़͞Ε͍ͯΔ tf.keras.Model.train_step ΛΦʔόʔϥΠυ͢Δ͜ͱͰɺࣗ༝ʹτϨʔχϯάϧʔϓΛ૊Ή͜ͱ͕ՄೳͰ͢*3ɻ ͜͏͢Δ͜ͱͰɺͨͱ͑͹ҎԼͷΑ͏ͳར఺͕ಘΒΕ·͢ɻ • compile ͕༏लɿ͞·͟·ͳͱ͜ΖͰ࢖͍·ΘͤΔ – model.save ͷࡍʹ compile Ͱઃఆͨ͠৘ใͷอଘ΋ͯ͘͠ΕΔ – ֶश్தͷ Optimizer ͷঢ়ଶอଘ΋อଘͯ͘͠ΕΔͷͰద੾ͳֶशͷ෮چ͕Մೳ – TensorBoard ίʔϧόοΫͳͲɺ͜͜Ͱઃఆͨ͠ϩε΍ϝτϦΫεΛࣗಈͰه࿥ͯ͘͠ ΕΔ • ศརͳίʔϧόοΫΛ؆୯ʹ࢖͑Δ – Learning Rate εέδϡʔϧ΍ TensorBoard ίʔϧόοΫͳͲɺ༏लͳ΋ͷ͕ଟ͍ ٯʹɺtf.keras.Model.train_step ΛΦʔόʔϥΠυ͢Δ࣮૷Λ͠ͳ͍৔߹ɺ͜ΕΒΛࣗલͰ ࣮૷͠ͳ͚Ε͹ͳΒͳ͘ͳΓɺίʔυྔ͕૿͑ͯݟӫ͕͑ѱ͘ͳͬͯ͠·͍·͢ɻ custom training roops Ͱ TensorBoard Λ࢖͏৔߹ train_summary_writer = tf.summary.create_file_writer(train_log_dir) test_summary_writer = tf.summary.create_file_writer(test_log_dir) for epoch in range(EPOCHS): *3 https://www.tensorflow.org/api_docs/python/tf/keras/Model?version=nightly#train_step 16
  19. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.3 SimCLR ͷ࣮૷

    for (x_train, y_train) in train_dataset: train_step(model, optimizer, x_train, y_train) with train_summary_writer.as_default(): tf.summary.scalar(’loss’, train_loss.result(), step=epoch) tf.summary.scalar(’accuracy’, train_accuracy.result(), step=epoch) for (x_test, y_test) in test_dataset: test_step(model, x_test, y_test) with test_summary_writer.as_default(): tf.summary.scalar(’loss’, test_loss.result(), step=epoch) tf.summary.scalar(’accuracy’, test_accuracy.result(), step=epoch) template = ’Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}’ print (template.format(epoch+1, train_loss.result(), train_accuracy.result()*100, test_loss.result(), test_accuracy.result()*100)) # Reset metrics every epoch train_loss.reset_states() test_loss.reset_states() train_accuracy.reset_states() test_accuracy.reset_states() ͦͷଞίʔυͷڞ௨Խ͕͠΍͍͢ͳͲͷཧ༝΋ؚΊɺtf.keras.Model ʹد࣮ͤͨ૷ʹ͍͖ͯ͠ ·͢ɻ 2.3 SimCLR ͷ࣮૷ ͦΕͰ͸ɺSimCLR ͷ࣮૷ͷ࿩ʹೖΓ·͢ɻtf.keras.Model ͷαϒΫϥεΛ࡞੒͠ɺҎԼͷΑ ͏ʹ train_step ΛΦʔόʔϥΠυ͠·͢ɻ Ϧετ 2.1: SimCLRModel Ϋϥεͷ࣮૷ class SimCLRModel(tf.keras.Model): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.data_augmentation = CustomAugment() self.global_batch_size = None self.emb_dim = None @tf.function def merge_fn(self, _, per_replica_res): return self.distribute_strategy.reduce( tf.distribute.ReduceOp.SUM, per_replica_res, axis=None) def train_step(self, x): 17
  20. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.3 SimCLR ͷ࣮૷

    x1 = self.data_augmentation(x) x2 = self.data_augmentation(x) x = tf.concat([x1, x2], 0) with tf.GradientTape() as tape: z = self(x) z = tf.math.l2_normalize(z, -1) z1, z2 = tf.split(z, 2, 0) z = tf.concat([z1, z2], -1) """===෼ࢄ࣮ߦͨ݁͠ՌΛϚʔδ͢ΔͨΊͷॲཧ===""" replica_context = tf.distribute.get_replica_context() replica_id = replica_context.replica_id_in_sync_group num_replicas = replica_context.num_replicas_in_sync per_replica_res = tf.scatter_nd( indices=[[replica_id]], updates=[z], shape=[num_replicas] + \ [int(self.global_batch_size / num_replicas), self.emb_dim * 2]) z = tf.distribute.get_replica_context()\ .merge_call(self.merge_fn, args=(per_replica_res,)) """===͜͜·Ͱ===""" z = tf.reshape(z, [-1] + z.shape.as_list()[2:]) zis, zjs = tf.split(z, 2, -1) loss = self.compiled_loss(zis, zjs) gradients = tape.gradient(loss, self.trainable_variables) self.optimizer.apply_gradients(zip(gradients, self.trainable_variables)) return {m.name: m.result() for m in self.metrics} tf.keras.Model ΫϥεͷΦϒδΣΫτΛ࡞Δ୅ΘΓʹɺ͜ͷϞσϧΫϥεͰϥοϓ͢Δ͚ͩͰ OK Ͱ͢ɻ SimCLRModel Ϋϥεͷར༻ from simclr import SimCLRModel from losses import simclr_loss_func #model = tf.keras.Model(inputs, outpus) model = SimCLRModel(inputs, outputs) model.compile(loss=simclr_loss_func, optimizer=optimizer, metrics=None) model.fit(~) 18
  21. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.3 SimCLR ͷ࣮૷

    ͪͳΈʹɺଛࣦؔ਺΋ SimCLR ༻ʹΧελϚΠζ͓ͯ͠ΓɺͦΕΛઃఆ͍ͯ͠·͢ɻcompile ͨ͠ ͋ͱ͸τϨʔχϯάϧʔϓͷதͰ self.compiled_loss ͰࢀরͰ͖·͢ɻ·ͨɺTensorBoard ίʔ ϧόοΫΛ࢖༻͍ͯ͠Δ࣌͸ɺcompile Ͱࢦఆͨ͠ଛࣦؔ਺ͷ໭Γ஋ʢlossʣ͕ TensorBoard Ͱه࿥ ͞Ε·͢ɻ SimCLR ͷଛࣦؔ਺ͷ࣮૷ def simclr_loss_func(zis, zjs): negative_mask = helpers.get_negative_mask(FLAGS.global_batch_size) l_pos = _dot_simililarity_dim1(zis, zjs) l_pos = tf.reshape(l_pos, (FLAGS.global_batch_size, 1)) l_pos /= FLAGS.temperature negatives = tf.concat([zjs, zis], axis=0) loss = 0 for positives in [zis, zjs]: labels = tf.zeros(FLAGS.global_batch_size, dtype=tf.int32) l_neg = _dot_simililarity_dim2(positives, negatives) l_neg = tf.boolean_mask(l_neg, negative_mask) l_neg = tf.reshape(l_neg, (FLAGS.global_batch_size, -1)) l_neg /= FLAGS.temperature logits = tf.concat([l_pos, l_neg], axis=1) loss += criterion(y_pred=logits, y_true=labels) loss = loss / (2 * FLAGS.global_batch_size) return loss TPU Strategy ͔͜͜Β෼ࢄֶशͷ࿩ʹೖΓ·͕͢ɺͦͷલʹ TPU ͷར༻ʹ͍ͭͯܰ͘࿩͠·͢ɻࠓճ͸ tf.di stribute.Strategy ͷ࣮૷ͷதͰ΋ɺTPUStrategy Λར༻͍ͯ͠·͢ɻ࢖༻͢ΔϞσϧ΍࣮૷ʹ Αͬͯগ͠มΘΔͱ͸ࢥ͍·͕͢ɺචऀͷ࣮ݧͰ͸ 1024 Ҏ্ͷόοναΠζͰֶश͢Δʹ͸ 8 ୆Ҏ ্ͷϚγϯ͕ඞཁʹͳΓ·͢ɻ ͜͜Ͱɺͨͱ͑͹ GCP Ͱ GPU ͱ TPU ͷྉۚΛൺֱͯ͠ΈΔͱɺϓϦΤϯϓςΟϒϧͷઃఆͰ ҎԼͷΑ͏ʹͳΓ·͢ɻ • NVIDIA š Tesla š V100 => $5.92/h*4 • Cloud TPU v3-8 => $2.4/h*5 ͜ͷΑ͏ʹɺTPU ͷํ͕ૣ্͍ʹίετ΋൒෼Ҏ্͍҆ͷͰɺSimCLR ͷΑ͏ͳେن໛ͳख๏Ͱ ݚڀ։ൃΛ͢Δͱ͖ʹ͸ TPU ͕ୈҰબ୒ࢶʹͳΔͱࢥ͍·͢ɻͦͷͨΊɺࠓճ͸ TPUStrategy ͷ *4 https://cloud.google.com/compute/gpus-pricing?hl=ja *5 https://cloud.google.com/tpu/pricing?hl=ja 19
  22. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.3 SimCLR ͷ࣮૷

    ར༻Λલఏͱ͍ͯ͠·͢ɻ ˞அΓΛೖΕ͍ͯΔͷ͸ɺ࣮͸࠷ۙϚϧν GPU ઃఆͰ MirroredStrategy Λࢼͨ͠ͱ͜Ζɺಉ ͡ίʔυͰΤϥʔ͕ग़ͯ͠·͍ɺݱࡏ͸मਖ਼͕ؒʹ߹͍ͬͯͳ͍ͷͰ͜ͷΑ͏ʹ͍ͯ͠·͢ɻ ɻ ෼ࢄֶश΁ͷରԠ෦෼ ͦΕͰ͸ɺ෼ࢄֶशͷ෦෼ʹೖΓ·͢ɻ·ͣɺ௨ৗͰ͋Ε͹ tf.keras.Model.fit ͷ৔߹ɺ෼ࢄ ֶशʹ͍ͨ͠ͱ͖͸ҎԼͷίʔυΛ௥ه͢Δ͚ͩͰಈ͖·͢*6ɻ tf.keras.Model.fit Ͱͷ෼ࢄֶशͷྫ mirrored_strategy = tf.distribute.MirroredStrategy() with mirrored_strategy.scope(): model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))]) model.compile(loss=’mse’, optimizer=’sgd’) model.fit(~) ͨͩ͠ɺSimCLR ͷ෼ࢄֶशରԠ͸͜͏؆୯ʹ͸͍͖·ͤΜɻτϨʔχϯάϧʔϓ͕ෳࡶʹͳΓɺ ෼ࢄͯ͠ॲཧͰ͖Δ෦෼ͱɺͦΕΒͷ݁ՌΛϚʔδͯ͠ΰχϣΰχϣ͢Δ෦෼͕͋ΔͨΊɺͦΕΒΛ ͏·࣮͘૷͢Δඞཁ͕͋Γ·͢ɻ͜ͷ͋ͨΓ͕৘ใ͕͋·Γͳ͘ɺ͘͢͝೉͍͠෦෼Ͱͨ͠ɻ ࣮૷͸ҎԼʹͳΓ·͢ɻͱ͍ͬͯ΋ɺ͢Ͱʹఏࣔͨ͠Ϧετ 2.1 ʹؚ·Ε͍ͯ·͢ɻ SimCLR ͷ෼ࢄֶशରԠ # ͍ͭ͘ͷσόΠεͰॲཧ͞Ε͍ͯΔ͔औಘ replica_context = tf.distribute.get_replica_context() replica_id = replica_context.replica_id_in_sync_group num_replicas = replica_context.num_replicas_in_sync # Ϛʔδ༻ʹ֤σόΠεͰॲཧதͷςϯιϧΛReshape per_replica_res = tf.scatter_nd( indices=[[replica_id]], updates=[z], shape=[num_replicas] + \ [int(self.global_batch_size / num_replicas), self.emb_dim * 2]) # Ϛʔδ͢ΔʢଞͷσόΠεͰܭࢉ͞Ε͍ͯͨαϯϓϧɺͭ·ΓωΨςΟϒαϯϓϧΛ߹ࢉʣ z = tf.distribute.get_replica_context()\ .merge_call(self.merge_fn, args=(per_replica_res,)) # Ҏ߱ͰϩεΛܭࢉ *6 https://www.tensorflow.org/guide/distributed_training#using_tfdistributestrategy_with_ tfkerasmodelfit 20
  23. ୈ 2 ষ SimCLR Λ TensorFlow2 Ͱ࣮૷ͯ͠Έͨ 2.4 ·ͱΊ Ҏ্͕

    SimCLR ͷ࣮૷ͷઆ໌ʹͳΓ·͢ɻઆ໌͖͠Ε͍ͯͳ͍෦෼΋͋Γ·͢ͷͰɺڵຯͷ͋Δ ํ͸ৄࡉ͸ҎԼͷϦϙδτϦΛࢀর͍ͯͩ͘͠͞ɻ https://github.com/tonouchi510/simclr-tf2-distribute 2.4 ·ͱΊ ݚڀ։ൃͷ࣮ࡍͷݱ৔Ͱ࢖͑Δ SimCLR ͷ࣮૷ʹ͍ͭͯ঺հͯ͠Έ·ͨ͠ɻݱࡏ͸ۀ຿Ͱ໨Լ࣮ ݧதͰ͋Γɺ·ͩνϡʔχϯά͢Δͱ͜Ζ·Ͱ͸Ͱ͖͍ͯ·ͤΜ͕ɺѱ͘ͳ͍݁Ռ͕ग़͍ͯΔͱࢥ͍ ·͢ɻ ݚڀ։ൃ͕͏·͍͚͘͹ɺSelf-Supervised Learning ͷ࣮຿Ԡ༻ͷέʔεͱͯ͠·ͨผͷػձͰ঺ հ͍ͨ͠ͱࢥ͍·͢ɻ 21
  24. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػ ೳͷ͘͠Έ 3.1 ࢝Ίʹ 2020

    ೥͸৽ܕίϩφ΢Οϧεͷײછ֦େʹ൐͍ɺԻָΤϯλʔςΠϯϝϯτͷ͋Γํ͕େ͖͘ม ֵͨ͠೥ͱͳΓ·ͨ͠ɻੜͷԻָΛௌ͖ʹϥΠϒϋ΢ε΁଍ΛӡΜͩΓɺΈΜͳͰΧϥΦέʹू·ͬ ͯՎΛָ͠ΜͩΓ͢Δ͜ͱ͸ҎલͷΑ͏ʹؾܰʹ͸Ͱ͖ͳ͍ঢ়گͱͳ͍ͬͯ·͢ɻΧϥΦέಈըί ϛϡχςΟΞϓϦ KARASTA*1Ͱ͸ɺ͜ͷΑ͏ͳঢ়گʹ͓͍ͯ΋ΈΜͳͰԻָΛָ͠ΊΔػೳͱ͠ ͯσϡΤοτػೳΛఏڙ͍ͯ͠·͢ɻຊষͰ͸ɺσϡΤοτػೳͷٕज़తͳ֓ཁ΍ Android ൛ͷΫ ϥΠΞϯτͷ࣮૷ʹ͍ͭͯ঺հ͠·͢ɻ 3.2 σϡΤοτػೳͱ͸ KARASTA ͷσϡΤοτػೳͱ͸ɺԕִ஍ʹ͍Δ 2 ਓͷϥΠϒ഑৴ऀ͕σϡΤοτͰΧϥΦέΛ Վ͏ػೳͷ͜ͱΛࢦ͠·͢ɻ Ϣʔβʔ͸εϚʔτϑΥϯΛ༻͍ͯϥΠϒ഑৴Λߦ͍ɺ഑৴தʹ͸ΞϓϦ಺ͷԻݯΛ࢖ͬͯΧϥΦ έΛՎ͏͜ͱ͕Ͱ͖·͢ɻ͞ΒʹɺϥΠϒ഑৴ͷࢹௌऀ͸ʮίϥϘਃ੥ʯΛ഑৴ऀʹૹΔ͜ͱͰ഑৴ ऀͱͯ͠ࢀՃ͢Δ͜ͱ΋Ͱ͖·͢ɻσϡΤοτػೳ͸͜ͷίϥϘ͕ߦΘΕ͍ͯΔؒʹར༻Ͱ͖Δػೳ Ͱ͢ɻ2 ਓͷ഑৴ऀ͕ಉָ͡ۂΛಉ࣌ʹՎ͍ɺࢹௌऀʹ͸ 2 ਓͷՎ੠͕߹Θͬͯ͞ௌ͑͜·͢ɻ *1 https://karasta.net/ 23
  25. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.3 ίϥϘ഑৴ͷ͘͠Έ ਤ 3.1:

    ഑৴ऀͷը໘ (ࠨ) ͱࢹௌऀͷը໘ (ӈ) ίϥϘػೳ͸ 2020 ೥ 3 ݄ʹఏڙΛ։࢝͠·͕ͨ͠ɺ͜ͷ࣌఺Ͱ͸ 2 ਓͷ഑৴ऀ͕ަޓʹιϩͰՎ ͏͜ͱ͔͠Ͱ͖·ͤΜͰͨ͠ɻ͜ͷͱ͖ʹσϡΤοτʹରԠ͍ͯ͠ͳ͔ͬͨཧ༝ͱͯ͠͸ɺޙड़͢Δ Α͏ʹ഑৴ͷ஗ԆΛߟྀͯ͠σϡΤοτΛ࣮ݱ͢ΔͨΊͷٕज़తϋʔυϧ͕ߴ͔ͬͨ͜ͱ΍ɺίϥϘ ػೳʹର͢ΔϢʔβʔ͔Βͷ൓ԠΛ౿·͑ͯσϡΤοτػೳͷ࢓༷Λݕ౼͔ͨͬͨ͜͠ͱ͕ڍ͛ΒΕ ·͢ɻݱࡏͷଟछଟ༷ͳϥΠϒ഑৴ϓϥοτϑΥʔϜͷதͰ΋ΧϥΦέͷσϡΤοτػೳΛఏڙͯ͠ ͍ΔαʔϏε͸ඇৗʹ·ΕͰ͋Γɺٕज़తͳ໘Ͱ΋࢓༷తͳ໘Ͱ΋ख୳Γͷঢ়ଶͰ։ൃʹऔΓ૊Έ· ͨ͠ɻ 2020 ೥ 5 ݄ʹ͸σϡΤοτػೳΛϦϦʔε͠ɺݱࡏͰ͸ଟ͘ͷϢʔβʔ͕ԕִ஍ͰͷΧϥΦέΛ ָ͠Ήखஈͱͯ͠σϡΤοτػೳΛར༻͍ͯ͠·͢ɻ 3.3 ίϥϘ഑৴ͷ͘͠Έ ຊઅͰ͸ɺσϡΤοτʹ͍ͭͯͷղઆͷલʹίϥϘ഑৴ (2 ਓͰͷ഑৴) Λ࣮ݱ͢ΔͨΊͷΫϥΠΞ ϯτͷΞʔΩςΫνϟʹ͍ͭͯղઆ͠·͢ɻ ϥΠϒ഑৴ͰίϥϘ͕։࢝͞ΕΔͱɺίϥϘΛਃ੥ͨ͠ϢʔβʔଆͰ͸ࢹௌը໘͔Β഑৴ը໘ʹ੾ ΓସΘΓɺίϥϘ͕ऴྃ͢Δͱ࠶ͼࢹௌը໘ʹ໭Γ·͢ɻࢹௌը໘ͱ഑৴ը໘Ͱ͸ը໘ϨΠΞ΢τ΍ ػೳ͕େ͖͘ҟͳΓ·͢ɻͨͱ͑͹ίϥϘΛਃ੥͢Δػೳ͸ࢹௌը໘ͷΈʹଘࡏ͠ɺΧϝϥ΍ϚΠΫ ΁ͷΞΫηε͸഑৴ը໘ͷΈͰඞཁʹͳΓ·͢ɻҰํͰɺ഑৴தͷίϝϯτͳͲͷදࣔ͸ը໘͕੾Γ ସΘͬͯ΋อ࣋͞Εଓ͚Δඞཁ͕͋Γ·͢ɻ 24
  26. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.3 ίϥϘ഑৴ͷ͘͠Έ KARASTA Ͱ͸͜ͷΑ͏ͳը໘ભҠΛ࣮૷͢ΔͨΊʹ

    Jetpack ͷ Navigation ͱ ViewModel Λ ׆༻͍ͯ͠·͢ɻ Navigation Navigation Λར༻͢ΔͱɺφϏήʔγϣϯάϥϑͱݺ͹ΕΔ XML ϦιʔεʹΑͬͯը໘ભҠΛ γϯϓϧʹهड़Ͱ͖·͢ɻҎԼʹφϏήʔγϣϯάϥϑͷྫΛࣔ͠·͢ɻ ࢹௌը໘ͱ഑৴ը໘Λ੾Γସ͑ΔφϏήʔγϣϯάϥϑͷྫ <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/live_nav_graph" app:startDestination="@id/audience"> <fragment android:id="@+id/audience" android:name="jp.co.mixi.karasta.live.audience.AudienceFragment"> <action android:id="@+id/action_audience_to_broadcaster" app:destination="@id/broadcaster" /> <action android:id="@+id/action_request_match" app:destination="@id/request_match" /> </fragment> <fragment android:id="@+id/broadcaster" android:name="jp.co.mixi.karasta.live.broadcaster.BroadcasterFragment"> <action android:id="@+id/action_broadcaster_to_audience" app:destination="@id/audience" app:popUpTo="@id/audience" app:popUpToInclusive="true" /> </fragment> <dialog android:id="@+id/request_match" android:name="jp.co.mixi.karasta.live.audience.requestmatch.RequestMatchDialog" /> </navigation> φϏήʔγϣϯάϥϑʹ͸ϑϥάϝϯτͷ΄͔ʹμΠΞϩάϑϥάϝϯτ΋௥ՃͰ͖ΔͷͰɺίϥ Ϙਃ੥࣌ͳͲʹදࣔ͞ΕΔμΠΞϩά΋ը໘ભҠͷҰͭͱͯ͠هड़Ͱ͖·͢ɻࢹௌը໘ ( Audience Fragment ) ͰίϥϘਃ੥Λ͢Δʹ͸ findNavController().navigate(R.id.action_request_ 25
  27. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.3 ίϥϘ഑৴ͷ͘͠Έ match) Λ࣮ߦ͠ɺίϥϘ͕ঝೝ͞ΕͨΒ

    findNavController().navigate(R.id.action_audi ence_to_broadcaster) Λ࣮ߦ͢Δͱ഑৴ը໘ ( BroadcasterFragment ) ʹ੾ΓସΘΓ·͢ɻ ഑৴ը໘ͱࢹௌը໘ͷΠϯελϯε͕όοΫελοΫʹҰ͔ͭͣͭ֨͠ೲ͞Εͳ͍Α͏ʹ͢Δ ͨΊɺࢹௌը໘ʹ໭ΔΞΫγϣϯͰ͋Δ action_broadcaster_to_audience ʹ͸ app:popUpTo ͱ app:popUpToInclusive Λࢦఆ͍ͯ͠·͢ɻapp:popUpTo Ͱ͸ΞΫγϣϯͷભҠઌͰ໭ΔφϏ ήʔγϣϯ͕࣮ߦ͞Εͨͱ͖ʹͲ͜ʹ໭Δ͔ΛࢦఆͰ͖·͢ɻapp:popUpToInclusive Λ true ʹ ͢Δͱɺ app:popUpTo Ͱࢦఆͨ͠໭Γઌ͕όοΫελοΫ͔Β࡟আ͞Ε·͢ɻ ViewModel ϥΠϒ഑৴ͷίϝϯτ΍഑৴࢒Γ࣌ؒͳͲͷ৘ใ͸ࢹௌը໘ͱ഑৴ը໘ͷ྆ํͰදࣔ͠ɺը໘ભҠ ࣌ʹ΋อ࣋͢Δඞཁ͕͋Γ·͢ɻ͜ͷΑ͏ʹෳ਺ͷը໘Ͱڞ༗͍ͨ͠σʔλΛอ࣋͢ΔͨΊʹ͸ɺΞ ΫςΟϏςΟΛείʔϓͱͨ͠ ViewModel Λ༻͍·͢ɻJetpack ͷ ViewModel ίϯϙʔωϯτʹ ͸ɺΞΫςΟϏςΟ΍ϑϥάϝϯτͷϥΠϑαΠΫϧΛείʔϓͱͨ͠σʔλΛอ࣋ͤ͞Δ͜ͱ͕Ͱ ͖·͢ɻΞΫςΟϏςΟΛείʔϓͱͨ͠ ViewModel Λ֤ϑϥάϝϯτ͔Βࢀর͢Δ͜ͱͰϑϥά ϝϯτؒͰͷσʔλͷड͚౉͠͸ෆཁʹͳΓɺ֤ϑϥάϝϯτ͕΄͔ͷϑϥάϝϯτͷ࣮૷΍ϥΠϑ αΠΫϧʹӨڹΛड͚Δ͜ͱ͸ͳ͘ͳΓ·͢ɻ ਤ 3.2: ϑϥάϝϯτؒͰͷσʔλڞ༗ ΞΫςΟϏςΟΛείʔϓͱͨ͠ ViewModel ͸ɺFragment KTX ʹؚ·ΕΔ activityViewMo dels() Λ࢖༻ͯ͠ҎԼͷΑ͏ʹ؆୯ʹऔಘͰ͖·͢ɻ 26
  28. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.4 σϡΤοτͷ͘͠Έ ΞΫςΟϏςΟΛείʔϓͱͨ͠ ViewModel

    ͷऔಘ class AudienceFragment : Fragment() { private val liveViewModel: LiveViewModel by activityViewModels() private val audienceViewModel: AudienceViewModel by viewModels() } class BroadcasterFragment : Fragment() { private val liveViewModel: LiveViewModel by activityViewModels() private val broadcasterViewModel: BroadcasterViewModel by viewModels() } class LiveViewModel : ViewModel() { // ࢹௌը໘ͱ഑৴ը໘Ͱڞ༗͍ͨ͠σʔλ΍ػೳ } class AudienceViewModel : ViewModel() { // ࢹௌը໘ͷΈʹඞཁͳσʔλ΍ػೳ } class BroadcasterViewModel : ViewModel() { // ഑৴ը໘ͷΈʹඞཁͳσʔλ΍ػೳ } 3.4 σϡΤοτͷ͘͠Έ ຊઅͰ͸σϡΤοτΛ࣮ݱ͢ΔͨΊͷٕज़తͳ͘͠Έʹ͍ͭͯ঺հ͠·͢ɻ ஗Ԇͷ͋Δ؀ڥԼͰσϡΤοτ͢Δʹ͸ ϥΠϒ഑৴ʹ͸஗Ԇ͕͋ΔͷͰɺ2 ਓͷ഑৴ऀ͕͓ޓ͍ͷՎ੠Λௌ͖ͳ͕ΒσϡΤοτ͢Δ͜ͱ͸ Ͱ͖·ͤΜɻ஗Ԇͯ͠ಧ͍ͨՎ੠ʹ߹ΘͤͯՎ͏ͱɺͦͷՎ੠΋૬खʹ͸஗Εͯௌ͑͜Δ͔ΒͰ͢ɻ ഑৴ͷ஗Ԇ͕͋Δঢ়گͰࢹௌऀʹՎ͕ͦΖ͍ͬͯΔΑ͏ʹௌ͔ͤΔͨΊʹ͸ɺҎԼͷ 2 ͭͷํ๏͕ߟ ͑ΒΕ·͢ɻ 1. ήετ (ίϥϘࢀՃऀ) ͷՎ੠ʹ߹Θͤͯϗετ (ϥΠϒ഑৴ऀ) ͕Վ͍ɺϗετͱήετͷՎ ੠ΛϗετଆͰ߹੒ͯ͠ࢹௌऀʹಧ͚Δ 2. ϗετͱήετ͕ಉ࣌͡ࠁʹԻݯΛ࠶ੜ͠ɺ྆ऀ͕ͦͷԻݯʹ߹ΘͤͯՎ͏ 27
  29. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.4 σϡΤοτͷ͘͠Έ ਤ 3.3:

    ஗Ԇͷ͋Δ؀ڥԼͰσϡΤοτ͢Δํ๏ 1. ͷํ๏͸ϗετ͕ήετͷՎ੠Λௌ͖ͳ͕ΒՎ͑ΔϝϦοτ͕͋ΔͷͰɺ·ͣ͸͜ͷํ๏Ͱϓϩ τλΠϐϯάΛߦ͍·ͨ͠ɻͦͷ݁ՌɺҎԼͷཧ༝͔Β 1. ͷํ๏͸ KARASTA ͷσϡΤοτʹ͋ ·Γద͍ͯ͠ͳ͍ͱ͍͏݁࿦ʹࢸΓ·ͨ͠ɻ • ϗετଆͰ 2 ਓͷө૾ͱԻ੠Λ߹੒͠ͳ͕Β഑৴͢ΔͨΊʹ͸͋Δఔ౓ͷ୺຤εϖοΫ͕ඞཁ ʹͳΔ • ϗετଆʹ͸഑৴ऀؒͷ஗ԆΛߟྀͯ͠ՎࢺΛදࣔ͢Δඞཁ͕͋Γɺ഑৴͕ෆ҆ఆʹͳͬͯՎ ࢺ͕ͣΕͨ৔߹ʹՎ͏ͷ͕ࠔ೉ʹͳΔ • ࢹௌऀଆͰ͸σϡΤοτதͱͦ͏Ͱͳ͍ͱ͖Ͱө૾Λ੾Γସ͑Δ͜ͱʹͳΓɺͦͷλΠϛϯά Ͱը໘ͷͪΒ͖͕ͭൃੜ͢Δ 2. ͷํ๏Ͱ͸ɺҰํͷ഑৴ऀͷ؀ڥ͕ෆ҆ఆʹͳΔͱࢹௌऀଆͰԻͣΕ͕ൃੜ͢ΔՄೳੑ͕͋Γ· ͢ɻ·ͨ഑৴ऀʹͱͬͯ͸͓ޓ͍ͷՎ੠Λௌ͔ͣʹՎ͏͜ͱʹͳΔͷͰɺҙࢥૄ௨͕೉͔ͬͨ͠Γ͖ Ε͍ʹௌ͍͑ͯ͜Δ͔ෆ҆ʹͳͬͨΓ͢Δͱ͍ͬͨ໰୊఺΋͋Γ·͢ (഑৴ͷΞʔΧΠϒػೳͰ͋ͱ ͔Β֬ೝ͢Δ͜ͱ͸Ͱ͖·͢)ɻ͔͠͠ͳ͕Βɺ҆ఆͨ͠؀ڥԼͰ͸͓͓ΉͶ͖Ε͍ʹͦΖͬͯௌ͜ ͑Δͱ෼͔ͬͨͨΊɺKARASTA Ͱ͸ 2. ͷํ๏ͰσϡΤοτػೳΛ࣮૷͠·ͨ͠ɻ ഑৴ऀؒͰͷσʔλͷ΍ΓͱΓ KARASTA Ͱ͸഑৴தʹߦΘΕΔϦΞϧλΠϜͳΠϕϯτΛૹड৴͢ΔͨΊʹ AWS IoT*2Λར ༻͍ͯ͠·͢ɻૹड৴͞ΕΔΠϕϯτʹ͸େ͖͘෼͚ͯ 2 छྨ͋Γ·͢ɻ1 ͭ໨͸ࢹௌऀͱ഑৴ऀͷ ྆ํʹૹ৴͞ΕΔΠϕϯτͰɺ഑৴ͷίϝϯτ΍഑৴ऴྃͷ௨஌ͳͲ͕ͦΕʹ֘౰͠·͢ɻ΋͏Ұͭ ͸഑৴ऀؒͰૹड৴͞ΕΔΠϕϯτͰ͢ɻσϡΤοτத͸഑৴ऀؒͰָۂͷ࠶ੜ΍ΩʔมߋͳͲͷΠ *2 https://aws.amazon.com/iot/ 28
  30. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.4 σϡΤοτͷ͘͠Έ ϕϯτΛ΍ΓͱΓͯ͠ঢ়ଶΛಉظ͠·͢ɻ ਤ

    3.4 ͸σϡΤοτػೳͰૹड৴͞ΕΔΠϕϯτΛ࣌ܥྻʹࣔͨ͠΋ͷͰ͢ɻ͔͜͜Β͸σϡΤο τͷྲྀΕͱ഑৴ऀؒͰঢ়ଶΛಉظ͢Δํ๏ʹ͍ͭͯઆ໌͠·͢ɻ ਤ 3.4: σϡΤοτͷྲྀΕ 29
  31. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.4 σϡΤοτͷ͘͠Έ σϡΤοτ։࢝·ͰͷྲྀΕ ίϥϘ഑৴த͸ϗετ·ͨ͸ήετָ͕ۂΛબ୒͠ɺԻݯ΍ՎࢺͷσʔλΛμ΢ϯϩʔυ͠·͢ɻ

    μ΢ϯϩʔυ͕׬ྃͨ͠ΒɺબۂΛ͍ͯ͠ͳ͍ଆʹ͸σϡΤοτΛਃ੥͢ΔϘλϯ͕දࣔ͞Ε·͢ɻ σϡΤοτΛਃ੥͢Δͱɺਃ੥ͨ͠ϢʔβʔଆͰ΋ಉָ͡ۂͷԻݯ΍Վࢺͷσʔλ͕μ΢ϯϩʔυ͞ Ε·͢ɻ ϗετͱήετͰָۂͷμ΢ϯϩʔυ͕Ͱ͖ͨΒɺબۂऀଆʹσϡΤοτΛ։࢝͢ΔͨΊͷ࠶ੜϘ λϯ͕දࣔ͞Ε·͢ɻ Իݯͷ࠶ੜҐஔΛಉظ͢Δํ๏ ήετͱϗετ͕ԻݯΛμ΢ϯϩʔυͨ͠Βɺ഑৴ऀؒͰ͸ҎԼͷ 4 छྨͷΠϕϯτΛ΍ΓͱΓ͠ ͯԻݯͷ࠶ੜঢ়ଶΛಉظ͠·͢ɻ • ࠶ੜ։࢝ • Ұ࣌ఀࢭ • Ωʔมߋ • ςϯϙมߋ ͜ΕΒͷ͏ͪɺ࠶ੜҐஔͷಉظ͸࠶ੜ։࢝ͱςϯϙมߋͷΠϕϯτ͕ૹड৴͞Εͨͱ͖ʹ࣮ߦ͞Ε ·͢ɻ ࠶ੜ։࢝ ࠶ੜ։࢝ͷΠϕϯτʹ͸࠶ੜ։࢝࣌ࠁͱ࠶ੜҐஔͷ৘ใؚ͕·Ε·͢ɻ • ࠶ੜ։࢝࣌ࠁɿԻݯͷ࠶ੜΛ։࢝͢Δ࣌ࠁɻ஗ԆΛߟྀͯ͠ૹ৴ଆ͸ݱࡏ࣌ࠁ +3 ඵͷ࣌ࠁΛ ૹ৴͢Δɻ഑৴ը໘ʹ͸࠶ੜ͞ΕΔ·ͰʹΧ΢ϯτμ΢ϯͷ਺ࣈ͕දࣔ͞ΕΔɻ • ࠶ੜҐஔɿԻݯͷ࠶ੜΛ։࢝ͨ͠ͱ͖ͷ࠶ੜҐஔɻ͜ΕʹΑͬͯҰ࣌ఀࢭதʹۂΛγʔΫͯ͠ ࠶։ͯ͠΋ਖ਼͘͠ಉظͰ͖Δɻ ݱࡏ࣌ࠁΛج४ʹ࠶ੜΛ։࢝͢ΔͷͰɺ഑৴ऀ͸ਖ਼֬ͳݱࡏ࣌ࠁΛ஌͍ͬͯΔඞཁ͕͋Γ·͢ɻ΋ ͠ϗετͱήετͷ୺຤Ͱݱࡏ࣌ࠁ͕ͣΕ͍ͯͨ৔߹ɺͦͷ͚࣌ؒͩԻݯ͕ͣΕͯ࠶ੜ͞Εͯ͠·͍ ·͢ɻ͜ΕΛ๷͙ͨΊʹɺσϡΤοτ࣌͸ OS ͔ΒऔಘͰ͖Δ࣌ࠁͰ͸ͳ͘ΞϓϦଆͰ NTP ͔Β௚ ઀औಘͨ࣌͠ࠁΛࢀর͍ͯ͠·͢ɻ ςϯϙมߋ KARASTA ʹ͸Իݯͷ࠶ੜςϯϙΛมߋͰ͖Δػೳ͕උΘ͍ͬͯ·͢ɻςϯϙ͸Իݯͷ࠶ੜதͰ ͋ͬͯ΋มߋͰ͖·͢ɻԻݯͷ࠶ੜҐஔΛม͑ͣʹεϜʔζʹςϯϙΛมߋ͢ΔͨΊʹɺ·ͣʮมߋ ޙͷςϯϙͰԻݯΛ࠷ॳ͔Β࠶ੜͨ͠ͱ͖ʹݱࡏͷ࠶ੜҐஔʹ͍ΔͨΊʹ͸͍ͭ࠶ੜΛ։࢝ͨ͠ΒΑ 30
  32. ୈ 3 ষ KARASTA Android ൛ͷσϡΤοτػೳͷ͘͠Έ 3.5 ऴΘΓʹ ͍͔ʁʯΛٻΊ·͢ɻ͜ͷ஋͸ҎԼͷܭࢉʹΑͬͯٻΊΒΕ·͢ɻ ࣜ

    3.1: ࠶ੜ։࢝࣌ࠁͷ࠶ܭࢉ ࠶ੜ։࢝࣌ࠁ = ݱࡏ࣌ࠁ − ݱࡏͷԻݯͷ࠶ੜҐஔ − લճ࠶ੜ։࢝ͨ͠ͱ͖ͷ࠶ੜҐஔ มߋޙͷςϯϙ ͜͜Ͱͷςϯϙ͸࠶ੜ଎౓ͷഒ཰ (౳଎ͳΒ 1.0) Λࢦ͠·͢ɻςϯϙΛมߋͨ͠ͱ͖͸ɺ͜ͷܭࢉ ͰٻΊͨ࠶ੜ։࢝࣌ࠁͱςϯϙΛ߹Θͤͯૹ৴͠·͢ɻड৴ଆͰ͸ҎԼͷܭࢉʹΑͬͯݱࡏͷ࠶ੜҐ ஔΛิਖ਼͠·͢ɻ ࣜ 3.2: ςϯϙมߋޙͷ࠶ੜҐஔͷܭࢉ ࠶ੜҐஔ = (ݱࡏ࣌ࠁ−ड৴ͨ͠࠶ੜ։࢝࣌ࠁ)×ड৴ͨ͠ςϯϙ+લճ࠶ੜ։࢝ͨ͠ͱ͖ͷ࠶ੜҐஔ Πϕϯτͷૹ৴஗Ԇͷͳ͍ཧ૝తͳঢ়گԼͰ͸ݱࡏͷ࠶ੜҐஔͱܭࢉͰٻΊͨ࠶ੜҐஔ͕Ұக͠· ͢ɻΠϕϯτͷૹ৴஗Ԇ͸҆ఆ͍ͯ͠Ε͹ແࢹͰ͖Δ΄Ͳ୹͍ͷͰɺ࠶ੜҐஔΛ΄΅ม͑Δ͜ͱͳ͘ εϜʔζʹςϯϙ͕มΘΓ·͢ɻ ࠶ੜதͷԻͣΕରࡦ ΋͠ϗετͱήετͰಉ࣌ʹ࠶ੜΛ։࢝ͨ͠ͱͯ͠΋ɺ࣮ࡍʹ࠶ੜ͞ΕΔ·Ͱʹ͔͔ΔΦʔόʔ ϔουͷ࣌ؒ͸͍Ζ͍ΖͳཁҼ (OS ΍୺຤ෛՙͷঢ়ଶͳͲ) ͰมԽ͠·͢ɻ·ͨɺ࠶ੜதʹ΋୺຤ෛ ՙͳͲʹΑͬͯԻඈͼ͕ൃੜ͠ɺ͓ޓ͍ͷ࠶ੜҐஔ͕ͣΕͯ͠·͏Մೳੑ͕͋Γ·͢ɻ͜ΕΛ๷͙ͨ Ίʹɺ࠶ੜத͸ࣜ 3.2 ͷࠨลͱӈลΛఆظతʹൺֱ͢Δ͜ͱͰ࠶ੜҐஔͷͣΕΛิਖ਼͍ͯ͠·͢ɻࠨ ล>ӈลͷͱ͖͸ૣ͘ਐΈ͍͗ͯ͢ΔͷͰ࠶ੜ଎౓Λམͱ͠ɺࠨล<ӈลͷͱ͖͸஗Ε͍ͯΔͷͰ࠶ ੜ଎౓Λ্͛·͢ɻඍʑͨΔԻͷͣΕΛௐ੔͢ΔͨΊͷ଎౓มߋͰ͢ͷͰɺϢʔβʔ͕Վ͍ͳ͕Β͜ Εʹؾ෇͘͜ͱ͸·ͣ͋Γ·ͤΜɻ͔͠͠ͳ͕Βɺ͜ͷඍௐ੔Λ͠ͳ͚Ε͹ԻͷͣΕ͕஝ੵ͠ɺۂΛ Վ͍ऴΘΔ͜Ζʹ͸ 1 ඵҎ্ͷେ෯ͳͣΕ͕ൃੜ͢Δ৔߹΋͋Γ·͢ɻ ͜ͷΑ͏ʹɺ࠶ੜҐஔΛಉظ͢ΔͨΊʹ͸ਖ਼͍͠࠶ੜҐஔΛܭࢉ͢ΔͨΊͷ৘ใΛϗετͱήετ Ͱ΍ΓͱΓ͠ɺͦͷ͏͑Ͱਖ਼͍͠Ґஔ͔ΒͣΕͳ͍Α͏ʹద੾ʹ࠶ੜ଎౓Λίϯτϩʔϧ͢Δ͜ͱ͕ ॏཁͱͳΓ·͢ɻ 3.5 ऴΘΓʹ ࠓճ͸঺հ͠·ͤΜͰ͕ͨ͠ɺϥΠϒ഑৴ΞϓϦʹ͸ө૾ॲཧ΍ΦʔσΟΦॲཧͳͲͷϚϧνϝ σΟΞܥͷٕज़͕;ΜͩΜʹ੝Γࠐ·Ε͍ͯ·͢ɻ΄͔ͷδϟϯϧͷΞϓϦͷ։ൃͰ͸͋·Γ࢖Θ Εͳ͍Α͏ͳઐ໳஌͕ࣝඞཁʹͳΔ͜ͱ΋͋Γ·͢ɻAndroid ʹ͓͚ΔϝσΟΞܥͷΞϓϦͷ։ൃ ͸೉қ౓͕ߴ͘ɺKARASTA Ͱ΋ OS ಛ༗ͷԻͣΕ΍୺຤ґଘͰൃੜ͢Δෆ۩߹ʹରॲ͢ΔͨΊʹ ೔ʑࢼߦࡨޡΛੵΈॏͶ͍ͯ·͢ɻ ҆ఆͨ͠ϥΠϒ഑৴ػೳΛఏڙ͢Δʹ͸·ͩ·ͩ՝୊΋͋Γ·͕͢ɺࠓޙ΋ՎΛ͞Βʹָ͠ΜͰ΋ Β͑ΔΑ͏ʹվળΛଓ͚͍͖͍ͯͨͱࢥ͍·͢ɻ 31
  33. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ ։ൃຊ෦ͷ౻ాͰ͢ɻ࠷ۙɺGo

    Λॻ͘ͱ͖ʹ͸Ͱ͖Δ͚ͩ Go ͷ࢓༷ॻΛಡΉΑ͏ʹ৺͕͚͍ͯ ΔͷͰ͕͢ɺ͍͟࢓༷ॻΛಡΜͰΈΔͱɺޡͬͨཧղΛ͍ͯͨ͠Օॴ͕ͨ͘͞Μग़͖ͯ·͢ɻࠓճ ͸ɺͦͷதͰ΋ Go ͷ interface ʹ͍ͭͯॻ͖͍ͨͱࢥ͍·͢ɻ 4.1 interface ͷجૅ஌ࣝ ·ͣɺinterface ͷجຊతͳ࢖͍ํʹ͍͓ͭͯ͞Β͍͓͖ͯ͠·͢ɻ Go ͷඪ४ύοέʔδͷ io ύοέʔδͰ͸ɺ࣍ͷΑ͏ͳ interface ͕ఆٛ͞Ε͍ͯ·͢ɻ type Writer interface { Write(p []byte) (n int, err error) } ͜ͷ interface ͸ Write(p []byte) (n int, err error) ͱ͍͏ϝιου͕ఆٛ͞Ε͍ͯΔܕ Λ૯শ͢ΔܕʹͳΓɺྻڍ͞Ε͍ͯΔϝιου͕ఆٛ͞Ε͍ͯΔ *1 ͢΂ͯͷܕͷ஋ΛೖΕΔ͜ͱ͕ Ͱ͖·͢ɻ ଟ͘ͷΦϒδΣΫτࢦ޲ݴޠ͕͍࣋ͬͯΔʮந৅ΫϥεʯͱΑ͘ࣅ͍ͯΔͨΊࠞಉ͞Ε͕ͪͰ͢ ͕ɺܕ෇͚͕໌֬ʹҧ͍·͢ɻ΄ͱΜͲͷந৅ΫϥεΛ࣋ͭΦϒδΣΫτࢦ޲ݴޠͷ৔߹ɺnominal typing ͱݺ͹ΕΔܕ෇͚Λ͓ͯ͠Γɺந৅ΫϥεΛ໌ࣔతʹܧঝ͍ͯ͠Δ͜ͱΛίʔυ্ʹදݱ͠ ·͢ɻ͔͠͠ɺGo ͷ interface ʹΑΔܕ෇͚͸ structural typing ͱݺ͹ΕΔ΋ͷͰɺͲͷ interface Λ࣮૷͍ͯ͠Δ͔Λ໌ࣔ͢ΔͷͰ͸ͳ͘ɺ࣮ࡍʹ interface Λ࣮૷͍ͯ͠Δ͔Ͳ͏͔Ͱܕ෇͚͠·͢ɻ structural typing ʹΑͬͯɺGo ͸ύοέʔδؒͷґଘΛগͳ͘Ͱ͖ΔԸܙΛड͚͍ͯ·͕͢ɺnil ΍ σϑΥϧτ஋ͱ૊Έ߹Θ͞Δ͜ͱͰෳࡶͳڍಈΛ͢Δ͜ͱ͕͋Γ·͢ɻຊষͰ͸ɺͦ͏͍ͬͨෳ ࡶͳڍಈΛ࢓༷ॻΛཔΓʹඥղ͍͍͖ͯ·͢ɻ ·ͨɺ༨ஊͰ͕͢ blank identify Λ࢖͏͜ͱͰɺnominal typing ͬΆ͘ interface Λ࢖͏͜ͱ͕ *1 ʮio.Writer Λ࣮૷͢Δʯͱݴ͍·͢ 33
  34. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.2

    interface ͷ಺෦දݱ Ͱ͖·͢ɻ type Hoge struct{} var _ = io.Writer(Hoge{}) ͜ͷΑ͏ʹ͓ͯ͘͜͠ͱͰɺߏ଄ମ Hoge ͕ io.Writer Λ࣮૷͍ͯ͠ͳ͔ͬͨ৔߹ɺίϯύΠϧΤ ϥʔʹͳΓ·͢ɻ 4.2 interface ͷ಺෦දݱ Go ͷܕʹ͸੩తܕͱಈతܕ *2 ͷ 2 छྨ͕͋Γ·͢ɻ Go ʹ͓͚Δ੩తܕͱ͸ɺએݴ࣌ʹਪ࿦ or ໌ࣔ͞Εͨܕɺnew ΍ෳ߹Ϧςϥϧ *3 Λ࢖ͬͯੜ੒͠ ͨ஋ͷܕɺߏ଄ମม਺ͷϑΟʔϧυͷܕͷ͜ͱͰɺཁ͢Δʹ୯ʹʮܕʯͱݺΜͰ͍Δ৔߹͸ɺ΄΅ؒ ҧ͍ͳ͘੩తܕͷ͜ͱΛࢦ͍͍ͯͯ͠·͢ɻ ରͯ͠ɺಈతܕ͸ interface ܕͷ஋͕಺෦తʹอ͍࣋ͯ͠ΔܕͰɺinterface ܕͷ஋ʹೖ͍ͬͯΔ஋ ͷ੩తܕׂ͕Γ౰ͯΒΕ·͢ɻinterface Λ࣮૷ͨ͠ผͷܕͷ஋Λ୅ೖ͢Ε͹ɺ౰વ interface ͷಈత ܕ͸৽͘͠୅ೖͨ͠஋ͷ੩తܕʹͳΓɺ࣮ߦதʹมԽ͢ΔܕͷͨΊಈతܕͱݺ͹Ε·͢ɻ ࣮ࡍʹίʔυͱ߹Θͤͯɺ੩తܕͱಈతܕʹ͍ͭͯݟ͍͖ͯ·͢ɻ package main import ( "fmt" "io" ) type ImplA struct{} func (ImplA) Write(_ []byte) (n int, err error) { return } type ImplB struct{} func (ImplB) Write(_ []byte) (n int, err error) { return } func main() { var w io.Writer w = ImplA{} fmt.Printf("%T\n", w) w = ImplB{} fmt.Printf("%T\n", w) *2 ໊લ͸Α͘ࣅ͍ͯ·͕͢ɺ ʮ੩తܕ෇͚ʯ ʮಈతܕ෇͚ʯͱ͸·ͬͨ͘ผͷ֓೦Ͱ͢ *3 Go Ͱ͸ߏ଄ମɺ഑ྻɺεϥΠεɺϚοϓͷϦςϥϧΛ૯শͯ͠ෳ߹Ϧςϥϧ (composite literals) ͱݺͼ·͢ɻ 34
  35. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.2

    interface ͷ಺෦දݱ } Go ͷ fmt.Printf() Ͱ࢖͑ΔϑΥʔϚοτࢦఆࢠ͸ fmt ύοέʔδͷυΩϡϝϯτ *4 ʹॻ͔Εͯ ͍·͢ɻ %T a Go-syntax representation of the type of the value %T Λࢦఆͨ͠৔߹ɺͦͷ஋ͷܕΛ Go ͷจ๏Ͱදݱͨ͠จࣈྻʹϑΥʔϚοτ͞Ε·͢ɻ಺෦త ʹ͸ reflect.TypeOf() Λ࢖ͬͯܕ৘ใΛऔಘ͓ͯ͠Γɺ reflect.TypeOf() ͷυΩϡϝϯτ *5 ΛಡΉ ͱɺ࣍ͷΑ͏ʹॻ͔Ε͍ͯ·͢ɻ func TypeOf(i interface{}) Type TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil. refrect.TypeOf() ͷҾ਺͕ interface{} ܕͰɺͦͷಈతܕΛฦ͠·͢ɻࠓճ͸Ҿ਺ʹ io.Writer ܕ ͷม਺ w Λ౉͍ͯ͠ΔͷͰɺ reflect.TypeOf() ͷҾ਺ i ͷಈతܕ = i ʹ୅ೖ͞Ε͍ͯΔ஋(ม਺ w )ͷ੩తܕ = io.Writer ͱ͍͏෩ʹղऍ͞Εͦ͏Ͱ͕͢ɺ࣮ࡍʹ͸࣮ߦ *6 ͯ͠ΈΔͱɺ࣍ͷΑ͏ʹදࣔ͞Ε·͢ɻ $ go run ./prog.go main.ImplA main.ImplB ͜Ε͸ͳͥͰ͠ΐ͏ɻ͜ͷٙ໰ͷ౴͑͸ Go blog *7 ʹॻ͔Ε͍ͯ·͢ɻ *4 https://pkg.go.dev/fmt#hdr-Printing *5 https://pkg.go.dev/reflect#TypeOf *6 Go Playground Ͱ࣮ߦͰ͖·͢ https://play.golang.org/p/dsfWPuG5DOx *7 https://blog.golang.org/laws-of-reflection 35
  36. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.3

    nil ͷܕ One important detail is that the pair inside an interface always has the form (value, concrete type) and cannot have the form (value, interface type). Interfaces do not hold interface values. ۩ମతͳཧ༝ͷղઆ͸ݩهࣄʹৡΔͱͯ͠ɺͱʹ͔͘ interface ܕ͕อ͍࣋ͯ͠Δ৘ใ͸ɺৗʹ஋ ͱ۩৅ܕ *8 ͷϖΞͰ͢ɻ ͋Δ interface ܕ A ͷม਺ʹɺ͋Δ interface ܕ B ͷ஋Λ୅ೖͯ͠΋ɺม਺ʹ B ͷ৘ใ͕อ࣋ ͞ΕΔ͜ͱ͸͋Γ·ͤΜɻͭ·Γ interface ܕͷม਺ʹ interface ܕͷ஋Λ୅ೖ͠Α͏ͱͨ͠৔߹ ʹݶͬͯɺͦͷม਺ͷಈతܕʹ͸஋ͷ੩తܕͰ͸ͳ͘ಈతܕׂ͕Γ౰ͯΒΕ·͢ɻͦͷͨΊɺҾ਺ ʹ interface ܕͰ͋Δ io.Writer ܕͷม਺Λ౉ͯ͠΋ɺio.Writer() ͷಈతܕͰ͋Δ main.ImplA ΍ main.ImplB ͕఻ൖ͞Ε͍ͯͨͷͰͨ͠ɻ ·ͨɺ͜ͷྫʹΑͬͯɺಈతܕ͕࣮ߦதʹมΘ͍༷ͬͯ͘ࢠ΋֬ೝͰ͖͔ͨͱࢥ͍·͢ɻ 4.3 nil ͷܕ ͢Ͱʹ interface ͷಈతܕͷෳࡶ͞Ͱे෼͓ෲ͍ͬͺ͍͔΋͠Ε·ͤΜ͕ɺ·࣮ͩࡍʹ࢖ͬͯΈΔ ͱ interface ʹ interface ΛೖΕͨ৔߹ʹɺೖΕࢠͷঢ়ଶʹͳΒͳ͍͓͔͛Ͱ reflect.TypeOf() ͕௚ ײతͳڍಈʹͳ͍ͬͯΔ͜ͱ͕෼͔Γ·͢ɻ͔͠͠ɺ͜͜ʹ nil ͕௥Ճ͞ΕΔ͜ͱͰ͞Βʹ࿩͸΍΍ ͘͜͠ͳΓ·͢ɻ ࣍ͷΑ͏ͳέʔεͰ͸ಈతܕʹ͸Կׂ͕Γ౰ͯΒΕΔͷͰ͠ΐ͏͔ʁ var a interface{} = nil ࣮͸ɺͦͷ౴͑΋࢓༷ॻʹهड़͕͋Γ·͢ *9 ɻ Variables of interface type also have a distinct dynamic type, which is the concrete type of the value assigned to the variable at run time (unless the value is the predeclared identifier nil, which has no type). ͳΜͱɺnil ͷܕ͕ͳ͍ *10 ৔߹͸ɺͦ΋ͦ΋ಈతܕ͸ׂΓ౰ͯΒΕ·ͤΜɻ ͱ͜ΖͰɺίʔυதͷ͞·͟·ͳ৔ॴʹొ৔͢Δ nil Ͱ͕͢ɺ͓ͦΒ͘΄ͱΜͲͷਓ͸ಛʹܕΛؾ *8 interface Ҏ֎ͷܕΛ۩৅ܕ (concrete type) ͱݺΜͰ͍·͢ *9 https://golang.org/ref/spec#Variables *10 ܕͷͳ͍ nil ͷ͜ͱΛ࢓༷ॻͰ͸ untyped nil ͱݺΜͰ͍·͢ 36
  37. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.4

    interface ͷൺֱ ʹͤͣʹ nil Λѻ͍ͬͯΔͱࢥ͍·͢ɻͦΕͰ͸ʮnil ͷܕ͕͋Δ৔߹ʯͱ͸ɺ͍͍ͬͨͲ͏͍ͬͨ ঢ়گͳͷͰ͠ΐ͏͔ɻ࣍ͷΑ͏ͳέʔε͕ nil ʹܕ͕͋Δঢ়ଶͰ͢ɻ var a *int = nil ͜ͷέʔεͰ͸ɺม਺ a ͸ʮ *int ܕͷ nil ʯͰ͢ɻnil Λ୅ೖͨ͠ΓΩϟετͨ͠Γ͢Δ͜ͱʹ Αͬͯɺnil ʹܕ͕༩͑ΒΕ·͢ɻnil Λ୅ೖͰ͖Δܕʹ͸੍ݶ͕͋Γɺ࢓༷ॻͰ͸ Assignability ͷ ষ *11 ʹॻ͔Ε͍ͯ·͢ɻ A value x is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies: - ʙলུʙ - ʙলུʙ - ʙলུʙ - ʙলུʙ - x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type. - ʙলུʙ ϙΠϯλɺؔ਺ɺεϥΠεɺϚοϓɺνϟωϧɺinterface ͸ nil Λ୅ೖͰ͖·͢ɻinterface ܕʹ ௚઀ nil Λ୅ೖ͢Δͱɺಈతܕ͸ׂΓ౰ͯΒΕ·ͤΜ͕ɺͦΕҎ֎ͷ nil Λڐ༰͢Δܕʹ nil ΛΩϟ ετͨ͠Γ୅ೖͨ͠ม਺Λ interface ʹ୅ೖ͢Δͱɺಈతܕׂ͕Γ౰ͯΒΕ·͢ɻ 4.4 interface ͷൺֱ લઅͰ͸ɺinterface ͷ nil ʹର͢ΔಛघͳڍಈΛ঺հ͠·͕ͨ͠ɺ͜Ε͚ͩͰ͋Ε͹ɺ݁ہ reflect ύοέʔδͰ΋࢖Θͳ͍ݶΓɺϓϩάϥϛϯάத͸ nil ͷܕʹ͍ͭͯҙࣝ͢Δඞཁ͸͋·Γ͋Γ·ͤ Μɻ͔͠͠ɺinterface ܕͷ஋ΛൺֱԋࢉࢠͷΦϖϥϯυʹ౉ͨ͠ͱ͖ɺ͜ͷ nil ͷ࢓༷ΛΑ͘ཧղ͠ ͍ͯͳ͍ͱ଍ݩΛ͘͢ΘΕΔ৔߹͕͋Γ·͢ɻ package main import "fmt" func main() { type intPointer *int var a interface{} *11 https://golang.org/ref/spec#Assignability 37
  38. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.4

    interface ͷൺֱ a = intPointer(nil) fmt.Println(a == nil) } interface{} ܕͷ a ʹ intPointer ܕʹΩϟετͨ͠ nil Λ୅ೖ͠ɺa ͱ nil Λ == ԋࢉࢠͰൺֱ͠ ͨ݁ՌΛग़ྗ͢ΔϓϩάϥϜͰ͢ɻ͜ͷϓϩάϥϜΛ࣮ߦ͢ΔͱͲͷΑ͏ͳ݁ՌʹͳΔͰ͠ΐ͏͔ʁ ௚ײతʹ͸ɺม਺ a ʹ͸ intPointer ܕʹΩϟετ͍ͯ͠Δͱ͸͍͑ɺ஋ͱͯ͠͸ nil ʹҧ͍ͳ͍ ͷ͔ͩΒɺม਺ a ͱ nil Λൺֱͨ݁͠Ռ͸ true ͕ฦ͖ͬͯͦ͏Ͱ͕͢ɺ࣮ࡍ *12 ʹ͸ false ͕ग़ྗ ͞Ε·͢ɻ $ go run ./prog.go false ͜Ε͸ɺinterface ͷൺֱʹؔ͢Δ࢓༷ͷͨΊͰ͢ɻComparison Operators *13 ͷষʹॻ͔Ε͍ͯ ·͢ In any comparison, the first operand must be assignable to the type of the second operand, or vice versa. The equality operators == and != apply to operands that are comparable. The ordering operators <, <=, >, and >= apply to operands that are ordered. These terms and the result of the comparisons are defined as follows: - Boolean values are comparable. Two boolean values are equal if they are either both true or both false. - Integer values are comparable and ordered, in the usual way. - Floating-point values are comparable and ordered, as defined by the IEEE-754 standard. - Complex values are comparable. Two complex values u and v are equal if both real(u) == real(v) and imag(u) == imag(v). - String values are comparable and ordered, lexically byte-wise. - Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal. - Channel values are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil. - Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil. - A value x of non-interface type X and a value t of interface type T *12 https://play.golang.org/p/u_4gZRJS7Ee *13 https://golang.org/ref/spec#Comparison_operators 38
  39. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.4

    interface ͷൺֱ are comparable when values of type X are comparable and X implements T. They are equal if t’s dynamic type is identical to X and t’s dynamic value is equal to x. - Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal. - Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal. - A comparison of two interface values with identical dynamic types causes a run-time panic if values of that type are not comparable. This behavior applies not only to direct interface value comparisons but also when comparing arrays of interface values or structs with interface-valued fields. Slice, map, and function values are not comparable. However, as a special case, a slice, map, or function value may be compared to the predeclared identifier nil. Comparison of pointer, channel, and interface values to nil is also allowed and follows from the general rules above. ௕͍ͷͰ interface ͕ؔΘΔ෦෼͚ͩ·ͱΊΔͱɺ== ԋࢉࢠͰ interface ܕͷ஋ͷൺֱʹؔ͢Δ ࢓༷͸ɺ࣍ͷ௨ΓͰ͢ɻ • interface Ͳ͏͠ͷൺֱ – ୈ 1 ϖϥϯυ͕ୈ 2 Φϖϥϯυͷܕʹ୅ೖՄೳͳΒൺֱՄೳ – ಈతܕͱͦͷ஋͕౳͍͠ͳΒ true Λฦ͢ – ྆ํͱ΋ untyped nil ͳΒ true Λฦ͢ – ಉҰͷಈతܕΛ͕࣋ͭɺͦͷܕ͕ൺֱෆՄೳͳΒ panic Λى͜͢ – ͦΕҎ֎ͳΒ false Λฦ͢ • interface ܕ T ͷ஋ t ͱඇ interface ܕ X ͷ஋ x ͷൺֱ – X ܕͷ஋͕ൺֱՄೳ͔ͭɺ X ͕ T Λ࣮૷͍ͯ͠ΔͳΒൺֱՄೳ – t ͷಈతܕ͕ X Ͱɺ t ͷ஋͕ x ʹ౳͍͠ͳΒ true Λฦ͢ – ͦΕҎ֎ͳΒ false Λฦ͢ • interface ஋ͱ untyped nil ͷൺֱ – interface ஋ͱ untyped nil ͸ൺֱՄೳ – interface ஋͕ untyped nil ͷ৔߹ true Λฦ͢ – ͦΕҎ֎ͳΒ false Λฦ͢ interface Ҏ֎ͷܕ͕Ͳ͏͍ͬͨ৔߹ʹൺֱՄೳͰɺͲ͏͍ͬͨ݁ՌΛฦ͢ͷ͔͸ݪจΛಡΜͰ ͍ͩ͘͞ɻ஫ҙ͠ͳ͚Ε͹ͳΒͳ͍ͷ͸ɺ࠷ޙͷ interface ஋ͱ untyped nil ͷൺֱͷ৔߹Ͱ͢ɻ untyped nil ͱͷൺֱͰ͸ɺinterface ஋ʹಈతܕ͕͋Δ৔߹͸໰౴ແ༻Ͱ false ʹͳͬͯ͠·͍·͢ɻ ͜ͷ໰୊͸ɺಛʹ error interface Λ࣮૷ͨ͠ܕΛ࢖͏৔߹ʹ஫ҙ͕ඞཁͰ͢ɻͨͱ͑͹ɺ࣍ͷΑ ͏ͳίʔυ͸Α͋͘Δͱࢥ͍·͢ɻ 39
  40. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.4

    interface ͷൺֱ type WrapError struct { err error } func (w *WrapError) Error() string { return "wrapped " + w.err.Error() } func wrap(err error) *WrapError { if err != nil { wrapped := &WrapError{err} return wrapped } return nil } error interface Λ࣮૷ͨ͠ߏ଄ମ WrapError Λఆ͍ٛͯ͠·͢ɻWrapError ͸೚ҙͷ error Λ ϥοϓͯ͠ग़ྗΛ੔ܗ͢Δ໨తͰఆٛ͞Εͨߏ଄ମͰ͢ɻͦͯ͠ɺ࣮ࡍʹ error Λϥοϓ͢Δؔ਺ Wrap(err error) Λఆٛ͠ɺҾ਺ʹ༩͑ͨ error ͕ nil ͷ৔߹ͷΈ WrapError Ͱϥοϓ͠ɺͦ͏Ͱ ͳ͍৔߹͸ nil Λฦ͍ͯ͠·͢ɻ ͦͯ͠ WrapError Λ࢖͏࣍ͷΑ͏ͳؔ਺Λఆٛ͠·͢ɻ func Hoge() (err error) { // Hoge() ಺Ͱൃੜͨ͠Τϥʔ͸ WrapError Ͱϥοϓͯ͠ฦ͍ͨ͠ defer func() { err = wrap(err) }() // ͳΜΒ͔ͷॲཧΛͨ݁͠ՌɺΤϥʔ͕ൃੜ͠ͳ͔ͬͨͱ͢Δ err = nil return err } func main() { err := Hoge() if err != nil { fmt.Println("Τϥʔൃੜ") } else { fmt.Println("ਖ਼ৗऴྃ") } } ؔ਺ Hoge() ͸ɺؔ਺಺Ͱൃੜͨ͠Τϥʔʹରͯ͠ defer ͷதͰ wrap() Λݺͼग़ͯ͠ WrapError Ͱϥοϓͯ͠ฦؔ͢਺Ͱ͢ɻࠓճ͸ݕূ༻ͷίʔυͰ͢ͷͰɺΤϥʔ͕ൃੜ͠ͳ͔ͬͨ૝ఆͰɺ err 40
  41. ୈ 4 ষ Go ͷ interface ͱ nil Λཧղ͢Δ 4.4

    interface ͷൺֱ ʹ͸ untyped nil ΛೖΕ͓͖ͯ·͢ɻ main() Ͱ͸ Hoge() Λݺͼग़ͯ͠ɺΤϥʔͷ༗ແΛ൑ఆ͍ͯ͠·͢ɻ ࣄલ஌ࣝͳ͠Ͱ͜ͷίʔυΛಡΉͱɺHoge() Ͱ͸ nil Λฦ͍ͯ͠Δ͠ɺdefer Ͱݺ͹Ε͍ͯΔ wrap() ΋ nil Λฦ͍ͯ͠ΔͷͰɺ ʮਖ਼ৗऴྃʯͱग़ྗ͞ΕΔͷͰ͸ͳ͍͔ͱײ͡Δͱࢥ͍·͢ɻ͔͠ ͠ɺ͜͜·ͰಡΜͩಡऀͷΈͳ͞ΜͳΒɺ࣮ࡍʹ͸ʮΤϥʔൃੜʯͱग़ྗ *14 ͞ΕΔ͜ͱ͕෼͔Δͱ ࢥ͍·͢ɻ ͜Ε͸ wrap() ͕ *WrapError Λฦ͍ͯ͠Δͷ͕ݪҼͰ͢ɻwrap() ͷ໭Γ஋ͷܕ͕ *WrapError ͷͨΊɺwrap() ΛݺΜͰ͍Δ Hoge() ʹ͸ɺ*WrapError ܕͷ nil ͕ฦ͖ͬͯ·͢ɻͦͷ஋Λ interface ܕͷม਺Ͱ͋Δ err ʹ୅ೖ͍ͯ͠ΔͨΊɺ err ͷಈతܕ͸ *WrapError ʹͳΓ·͢ɻ Hoge() ͸ͦͷ··ಈతܕ͕ *WrapError Ͱ஋͕ nil ͷ err Λ main() ʹฦ͠·͢ɻͦͷޙɺͦͷ err ͱ untyped nil Λൺֱ͍ͯ͠·͕͢ɺલड़ͷ௨Γɺinterface ஋ͱ untyped nil ͷൺֱ͸ɺinterface ஋΋ untyped nil Ͱ͋Δ৔߹ͷΈಉҰͰ͋ΔͱΈͳ͞Ε·͢ɻ݁Ռɺerr != nil ͕ true ʹͳͬͯ͠ ·͍ɺ ʮΤϥʔൃੜʯͱग़ྗ͞Εͯ͠·͍·͢ɻ ࠓճͷίʔυͰҙਤ௨Γʮਖ਼ৗऴྃʯͱग़ྗ͍ͤͨ͞ͳΒɺwrap() ͷ໭Γ஋ͷܕΛ error ͱ͢Δ ͱΑ͍ *15 Ͱ͢ɻ Έͳ͞ΜͳΒɺཧ༝͸΋ͪΖΜઆ໌Ͱ͖·͢ΑͶʁ *14 https://play.golang.org/p/JF_TeuXV8Bp *15 https://play.golang.org/p/ZxLdxLx3B8t 41
  42. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.1 ࢝Ίʹ 2020 ೥ੈքͰ࠷΋੒ޭͨ͠ήʔϜ͸ϚϧνϓϨΠ͕ओମͳήʔϜͰ͢ɻ͜ͷΑ͏ͳήʔϜ͸ٕज़

    త೉౓͕ߴ͍ͱࢥΘΕ͕ͪͰ͕͢ɺUnity DOTS Λ༻͍Ε͹؆୯ʹϋΠύϑΥʔϚϯεͳήʔϜΛ ࡞Δ͜ͱ͕Ͱ͖·͢ɻຊষͰ͸ͦΜͳ DOTS Λ׬શʹཧղ͢Δ଍͕͔Γͱͯ͠ɺUnity DOTS ͱ͸ Կ͔ɺͲͷΑ͏ʹॲཧΛߴ଎Խ͢Δͷ͔ɺϚϧνϓϨΠͷ͘͠ΈͳͲɺDOTS ͷ֤ٕज़ʹ͍ͭͯͲͷ Α͏ͳ΋ͷͳͷ͔֓ཁΛ৮Ε͍͖ͯ·͢ɻதͰ΋ಛʹɺAnimation ΍ Build ؔ࿈ͷ৘ใ͸·ͩ͋· Γͳ͍ͷͰ͕͢ɺݕূΛਐΊΔʹͭΕͯ෼͔͖ͬͯͨ͜ͱΛॻ͍ͨͷͰࢀߟʹ͍͚ͯͨͩͨ͠Β޾͍ Ͱ͢ɻຊষΛࢀߟʹগ͠Ͱ΋ DOTS ʹڵຯΛ࣋ͭɺௐ΂ͯΈΔͱ͍ͬͨ͜ͱ͕Ͱ͖ΔΑ͏ʹͳΔͷ ͕ຊষͷචऀͷئ͍Ͱ͢ɻ ˎຊষͷ಺༰͸ 2020 ೥ 12 ݄࣌఺ͷ΋ͷͰ͢ɻ಺༰͸มߋ͞ΕΔڪΕ͕͋Γ·͢ɻ 5.2 ϛΫγΟͰͷ Unity DOTS ΁ͷऔΓ૊Έ ϛΫγΟͰ͸ϚϧνϓϨΠήʔϜʹ͓͚Δٕज़ݕূͱͯ͠ Unity DOTS ʹऔΓ૊ΜͰ͍·͢ɻ ϚϧνϓϨΠήʔϜΛ࡞Δಈػ SuperData*1ʹΑΕ͹ɺ2020 ೥࠷΋੒ޭͨ͠ήʔϜ League of Legends ΍ Call of DutyɺFortnite ͷΑ͏ʹɺϚϧνϓϨΠ͕ओମͳήʔϜͰ͢ɻ ͜Ε·Ͱओྲྀͷ P2P Relay ํࣜͷΦϯϥΠϯԽͰ͸ɺ24 ਓΛ௒͑ΔϓϨΠϠʔΛಉظ͠Α͏ͱ͢ Δͱ໰୊͕ੜ͡Δ͜ͱ͕ଟ͍ͨΊɺઐ༻αʔόͰαʔόϥϯλΠϜΛಈ͔͢ํࣜ΁ͷҠߦ͕ਪ঑͞Ε ͍ͯ·͢ɻ·ͨɺηογϣϯ͝ͱͷϓϨΠϠʔͷ਺͕ 64 Λ௒͑Δ৔߹ʹ͸ Unity NetCode ͳͲͷ Unity DOTS Λ࢖༻͢Δ͜ͱ͕ਪ঑͞Ε͍ͯ·͢ɻ *1 https://www.superdataresearch.com/blog/worldwide-digital-games-market 43
  43. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.3 Unity DOTS ͱ͸

    ઐ༻ήʔϜαʔόͷϝϦοτ • νʔτ͕ൃੜͮ͠Β͍ ͨͱ͑͹ɺΞΠςϜͷऔಘ൑ఆ΍౰ͨΓ൑ఆͳͲΛαʔόͰߦ͏͜ͱ͕Ͱ͖ΔΑ͏ʹͳΔͷͰɺ νʔτ͕ൃੜͮ͠Β͍Ͱ͢ɻ ʢP2P Ͱ͸ Ban ͢ΔͳͲͷରࡦ͔͠Ͱ͖ͳ͍ʣ • ϨΠςϯγ଱ੑ P2P Relay Ͱ͸ϨΠςϯγ͕େ͖͘ͳΓɺ200 ϛϦඵະຬʹ཈͑ΒΕͳ͍͜ͱ͕ԟʑʹͯ͋͠Γɺ ϥά͕͋·Γൃੜͯ͠͸͍͚ͳ͍ήʔϜͰ͸ɺઐ༻αʔό͕ඞཁʹͳΔͱߟ͑ΒΕ·͢ɻ ͜ͷΑ͏ͳαʔόϥϯλΠϜ͸௨ৗ C++ ͳͲͰॻ͔ΕΔ͜ͱ͕ଟ͍ͱࢥ͍·͕͢ɺUnity DOTS ͷҰ෦Ͱ͋ΔɺTransport ΍ NetCode Λ࢖༻͢Δ͜ͱͰɺUnity ্Ͱ؆୯ʹαʔόϥϯλΠϜΛ࡞ ੒Ͱ͖·͢ɻ 5.3 Unity DOTS ͱ͸ Unity Ͱσʔλࢦ޲ઃܭ (Data Oriented Design) Λ͢ΔͨΊͷύοέʔδ܈Ͱ͢ɻ σʔλࢦ޲ઃܭͱ͸ʁ Unity ͷطଘͷίϯϙʔωϯτγεςϜʢMonobehaviourʣͳͲ͸ɺΦϒδΣΫτࢦ޲ͷߟ͑ํͰ ։ൃ͞Ε͍ͯ·͢ɻ͜͜਺೥Ͱ CPU ͷੑೳ͸ඈ༂తʹ޲্͠ɺ·ͨϚϧνίΞ౳ͷෳ਺ฒྻಉ࣌ܭ ࢉೳྗ΋खʹೖΕ·͕ͨ͠ɺϝϞϦͷ଎౓͸ͦ͜·Ͱߴ଎Խ͓ͯ͠ΒͣɺϝϞϦͷసૹ଎౓͕ CPU ੑೳΛҾ͖ग़্͢ͰͷϘτϧωοΫʹͳ͍ͬͯΔ͜ͱ͕ଟʑ͋Γ·͢ɻ ͨͱ͑͹ϝΠϯϝϞϦ͔ΒͷಡΈग़͠ʹ͸ɺ200 ΫϩοΫαΠΫϧҎ্͔͔Γɺ΋͠ॲཧ͕׬ྃ͠ ͨͳΒ͹ɺ৘ใ͕ಧ͘·Ͱͷؒ͸଴͕ͪ࣌ؒൃੜ͠·͢ɻ ҰํͰɺCPU ʹ͸ΩϟογϡʢL1ɺL2ʣͱ͍͏ߴ଎ʹಡΈॻ͖Ͱ͖ΔϝϞϦ΋ଘࡏ͠·͢ɻ͜ͷ Ωϟογϡʹ৐͍ͬͯΔ৘ใͷऔಘ͸ 3ʙ4 αΠΫϧͱඇৗʹ୹͍࣌ؒͰऔಘͰ͖ΔͷͰɺຖճϝΠ ϯϝϞϦ͔Βऔಘ͢Δͷʹൺ΂ͯѹ౗తʹޮ཰తͰ͢ɻ ϝϞϦۭؒͷࢄΒ͹Γ ΦϒδΣΫτࢦ޲Ͱ͸ɺΦϒδΣΫτ͸ϙΠϯλͱ͍͏ܗͰ഑ྻʹ֨ೲ͞Ε·͢ɻϙΠϯλΛ༻͍ ͯࢀরͱ͍͏ܗͰ֤ʑͷΦϒδΣΫτʹΞΫηεͰ͖Δ൓໘ɺ֤ΦϒδΣΫτ͸ϝϞϦ্ʹࢄΒ͹Δ ܗͰ഑ஔ͞Ε·͢ɻͦͷͨΊɺϝϞϦ͔ΒσʔλΛऔΓग़͢ͱ͖ʹԿ౓΋Ωϟογϡʹసૹ͢Δඞཁ ͕͋ΓɻΩϟογϡϛε͕ଟ͘ൃੜ͠·͢ɻ ͦ͜Ͱɺσʔλࢦ޲ઃܭͰ͸ɺϝϞϦϨΠΞ΢τΛݻΊͯɺՄೳͳݶΓσʔλΛϩʔυͯ͠Ωϟο γϡʹࡌͤΔ͜ͱͰɺCPU ͸ޮ཰తʹॲཧΛ࣮ߦͰ͖·͢ɻΩϟογϡ͸௨ৗߴ଎ʹ͢ΔͨΊɺඞ ཁͳσʔλΛ 1 όΠτͣͭͰ͸ͳ͘ɺ͋Δఔ౓ͷྔΛ·ͱΊͯసૹ͠·͢ɻ͜ͷͨΊɺ΋͠ඞཁͳ 44
  44. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.4 Entity Component System

    σʔλ͕গྔͩͱɺ΄͔ͷແؔ܎ͳσʔλͱͱ΋ʹϩʔυ͞Εͯ͠·͍ඇޮ཰Ͱ͢ɻͦͷͨΊϝϞϦ ϨΠΞ΢τΛݻΊ͓ͯ͘͜ͱ͸ߴ଎Խʹ͸ඇৗʹॏཁͰ͢ɻ·ͨɺΞΫηεର৅ΛܾΊͯҰؾʹॲཧ ͯ͠͠·͏ͷ͕ޮ཰తͰ͢ɻ͜ͷΑ͏ͳํࣜ͸ฒྻԽॲཧͳͲʹ΋޲͍͍ͯ·͢ɻ ҰํͰɺσʔλࢦ޲ઃܭ͸ΦϒδΣΫτࢦ޲ઃܭͱେ͖͘ҟͳΔ΋ͷͰ͢ͷͰɺϓϩάϥϚʔʹ͸ ཧղͮ͠Β͍Մೳੑ͕͋Γ·͢ɻ 5.4 Entity Component System σʔλࢦ޲ઃܭͰ࡞ΒΕͨ৽͍͠ Unity ͷγεςϜ͕ɺEntity Component SystemʢECSʣͰ͢ɻ ECS ͸ɺEntityɺComponentɺSystem ͷ 3 ͭͷཁૉ͔ΒͳΓ·͢ɻ௚ײతʹݴ͏ͱɺSystem ͕ৼ Δ෣͍Λఆٛ͢Δ΋ͷɺComponent ͕σʔλΛஔ͍͓ͯ͘৔ॴɺEntity ͸෺ͱͯ͠දݱ͞Ε·͢ɻ ͜ΕΒ͸ผʑʹ࣮૷͞ΕɺEntity ʹෳ਺छྨͷσʔλʢComponentʣΛઃఆͰ͖·͢ɻͦͯ͠ɺγ εςϜ͸Ұఆͷ Component Λ࣋ͭ Entity ʹରͯ͠ॲཧΛ࣮ߦ͠·͢ɻ ϫʔϧυ ϫʔϧυ͸ EntityɺComponentɺSystem Λแؚ͍ͯ͠Δ΋ͷͰ͢ɻϫʔϧυ͸͍ͭ͘Ͱ΋࡞੒ Ͱ͖·͕͢ɺϫʔϧυͲ͏͠ͷ௚઀తͳׯব͸Ͱ͖·ͤΜɻ ΞʔΩλΠϓ ΞʔΩλΠϓͱ͸ Entity ͷͻͳܕͷ͜ͱͰɺEntity ಺ͷ Component ͷ૊Έ߹ΘͤΛࢦ͠·͢ɻ Entity ͱ͸ίϯςφͷΑ͏ͳ΋ͷͰɺEntity ʹ Component Λ௥Ճͨ͠Γ࡟আͨ͠Γ͢Δ͜ͱͰɺ Entity ͷৼΔ෣͍Λ࡞Δ͜ͱ͕Ͱ͖ΔΑ͏ʹͳ͍ͬͯ·͢ɻ ࣮͸ Entity ʹ͸ ID ͕ઃఆ͞Ε͍ͯΔ͚ͩͰɺID ͔ΒΞʔΩλΠϓΛ༻͍Δ͜ͱͰ Component ܈ʹΞΫηε͍ͯ͠·͢ɻ νϟϯΫ Component Λ֨ೲ͢ΔϝϞϦۭؒΛ؅ཧ͢Δ΋ͷ͕νϟϯΫͰ͢ɻνϟϯΫʹ͸ಉҰͷΞʔΩλ Πϓ͔֨͠ೲ͠ͳ͍Α͏ʹͳ͓ͬͯΓɺ͋ΔνϟϯΫʹରͯ͠ෳ਺ͷΞʔΩλΠϓ͕ଘࡏ͢Δ͜ͱ ͸͋Γ·ͤΜɻٯʹΞʔΩλΠϓʹରͯ͠νϟϯΫ͸ෳ਺ଘࡏ͠·͢ɻ͜ΕʹΑΓେྔͷ Entity ͕ ଘࡏ͢Δ৔߹Ͱ΋ɺগྔͷΞʔΩλΠϓΛݕࡧ͢Δ͚ͩͰॲཧ͕࣮ߦͰ͖·͢ɻ·ͨɺνϟϯΫ͸࿈ ଓతʹϝϞϦۭؒʹଘࡏ͢ΔͨΊɺΩϟογϡϛεΛݮΒ͢͜ͱ͕Ͱ͖ɺॲཧ଎౓͕޲্͠·͢ɻ͜ ͷΑ͏ͳߏ଄ʹ͓ͯ͘͠ͱɺଟ͘ͷ৔߹ϚϧνεϨουͰॲཧ͠΍͘͢ɺECS Λૢ࡞͢Δίʔυ͸ 100% ͍ۙίΞ࢖༻཰Ͱ࣮ߦ͞Ε·͢ɻ 45
  45. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.5 C# Job System

    ਤ 5.1: ΞʔΩλΠϓͱνϟϯΫͷσβΠϯʢPackages Manual*2͔ΒҾ༻ʣ 5.5 C# Job System Job System*3͸ɺεϨουͳͲͷ୅ΘΓʹδϣϒΛ࡞੒ͯ͠ɺฒྻԽΛߦ͏ϚϧνεϨουίʔ υΛ؆୯ʹهड़Ͱ͖·͢ɻ·ͨ Burst Compiler Λར༻͢ΔͱίʔυΛ࠷దԽͰ͖ϞόΠϧσόΠε ͷόοςϦʔফඅྔ΋େ෯ʹ࡟ݮ͞Ε·͢ɻ࿦ཧίΞʢCPUʣ͝ͱʹ 1 ͭͷϫʔΧεϨου͕͋Γɺ ͦ͜Ͱ࡞੒ͨ͠ίʔυΛಈ͔ͯ͘͠Ε·͢ɻͦͷͨΊɺCPU ίΞΑΓଟ͘ͷεϨουΛ࡞੒͢Δ͜ ͱʹΑΔ CPU Ϧιʔεͷڝ߹ΛճආͰ͖·͢ɻܭࢉΛ҆શʹߦ͏ͨΊʹɺJob System Ͱૢ࡞͢Δ ඞཁͷ͋Δσʔλ͸ࢀরͰ͸ͳ͘ɺίϐʔΛ֤δϣϒʹૹ৴͢ΔͨΊͰεϨουηʔϑͰ͢ɻͪͳΈ ʹίϐʔͰ͖Δͷ͸ blit ςʔϒϧܕͷΈͰ͢ɻ Burst Burst*4͸ LLVM*5Λ࢖͍ɺSIMD ΍ϝϞϦΤΠϦΞεͷߟྀ౳ͷ࠷దԽ͕ՄೳͳɺωΠςΟϒ ίʔυΛੜ੒͢ΔίϯύΠϥͰ͢ɻSIMD ͱ͸ɺ̍ͭͷ໋ྩͰෳ਺ͷܭࢉΛߦ͏͘͠Έͷ͜ͱͰɺͨ ͱ͑͹ɺ4 ࣍ݩϕΫτϧͲ͏͠ͷՃࢉΛ࣮ߦ͢Δ৔߹ 32 ϏοτͷϨδελ෯Ͱ͸ 4 ճͷՃࢉ໋ྩ͕ ඞཁʹͳΓ·͕͢ɺ128 ϏοτͷϨδελͰҰճͰࡁΉΑ͏ʹͳΔͱ͍͏Α͏ͳ΋ͷͰ͢ɻαϙʔτ ͞Ε͍ͯΔܕ͸جຊతʹɺϓϦϛςΟϒܕɺϕΫτϧܕʢUnity Mathematicsʣ ɺྻڍܕɺߏ଄ମͳ ͲͰɺstring ͳͲϚωʔδυͳ΋ͷ͸αϙʔτ͞Ε͍ͯ·ͤΜɻ *2 https://docs.unity3d.com/Packages/[email protected]/manual/ecs_core.html *3 https://docs.unity3d.com/2020.1/Documentation/Manual/JobSystem.html *4 https://docs.unity3d.com/Packages/[email protected]/manual/index.html *5 ίϯύΠϥΛ࡞ΔͨΊͷϑϨʔϜϫʔΫ 46
  46. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.6 Unity NetCode 5.6

    Unity NetCode Unity NetCode*6͸ϚϧνϓϨΠϠʔήʔϜͰϫʔϧυಉظΛ࣮૷͢ΔͨΊʹඞཁͳϚϧνϓϨ ΠϠʔػೳΛఏڙ͍ͯ͠·͢ɻωοτϫʔΫͷ௿ϨϕϧϨΠϠʹ͸ Transport Package*7Λ࢖༻ͯ͠ ͍ͯɺDOTS ༻ʹ࡞੒͞Ε͍ͯ·͢ɻECS Λ࢖ͬͯαʔόϥϯλΠϜΛ Unity Ͱ؆୯ʹ੍࡞Ͱ͖Δ ύοέʔδͰ͢ɻ۩ମతʹ͸ EntityɺComponent Λࣗಈతʹಉظ͠ɺαʔόɺΫϥΠΞϯτʹΑͬ ͯ System Λ੍ޚͰ͖·͢ɻ Transport Package UNet Λஔ͖׵͑ΔύοέʔδͰ͢ɻ௨ৗͷαʔό΍઀ଓͳͲ͸ɺ͜ͷύοέʔδ͚ͩͰ࣮ߦͰ͖ ·͢ɻ Client server Worlds ΫϥΠΞϯτϩδοΫͱαʔόϩδοΫ͸ผʑͷϫʔϧυʹଘࡏ͠ɺDefault World ʹ͸Կ΋഑ஔ ͞Εͳ͍ͷͰ஫ҙ͕ඞཁͰ͢ɻ·ͨɺPlayMode Tools Ͱ͸αʔόͱΫϥΠΞϯτͷͲͪΒ͔ʢ·ͨ ͸྆ํʣΛ࣮ߦ͢Δ͔ɺϓϨΠϠʔͷ਺ɺϨΠςϯγͷγϛϡϨʔγϣϯͳͲΛઃఆͰ͖·͢ɻ Ghost Ghost ͱ͸ωοτϫʔΫԽ͞ΕͨΦϒδΣΫτͷ͜ͱͰɺαʔόΫϥΠΞϯτͰಉظ͍ͨ͠Φϒ δΣΫτ͸ Ghost Ͱ͋Δඞཁ͕͋Γ·͢ɻ Ghost Snapshots Ghost Snapshots ͸͢΂ͯͷ Ghost ͷঢ়ଶͷεφοϓγϣοτΛΫϥΠΞϯτʹಉظ͢Δγες ϜͰ͢ɻαʔό͸ෛՙͷؔ܎͔ΒɺEntity ͝ͱͰ͸ͳ͘ ECS νϟϯΫ͝ͱʹॲཧ͠·͢ɻΫϥΠΞ ϯτଆͰ͸ɺEntity ͝ͱʹॲཧ͕ߦΘΕ·͢ɻ Ghost Collection Ghost Collection ͱ͸ϓϨϋϒԽͨ͠ Ghost Λొ࿥͓ͯ͘͠΋ͷͰɺ͜ΕΛ࢖༻ͯ͠ɺαʔόΫ ϥΠΞϯτ্Ͱ Ghost ΛΠϯελϯεԽͯ͠ಉظͰ͖·͢ɻଞʹ΋ΠϯελϯεԽͨ͠ Ghost Λࣄ લʹ SubSence ͳͲʹ഑ஔ͓͍ͯͯ͠΋ಉظͰ͖·͢ɻ *6 https://docs.unity3d.com/Packages/[email protected]/manual/index.html *7 https://docs.unity3d.com/Packages/[email protected]/manual/index.html 47
  47. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.7 Unity Physics Entity

    ͷੜ੒ αʔό͔Β৽͍͠ Ghost Λड৴͢ΔͱɺΫϥΠΞϯτଆͰ Entity ͕ࣗಈతʹੜ੒͞Ε·͢ɻ Prediction ͷͨΊʹɺΫϥΠΞϯτଆͰ͸एׯ஗Ԇͯ͠ੜ੒͞Ε·͢ɻ Prediction Prediction ͱ͸ɺΫϥΠΞϯτ΋αʔόͱಉ͡ॲཧΛ࣮ߦ͠ɺΫϥΠΞϯτଆͷܭࢉϛε΍ϓϨΠ ϠʔͷӨڹ͕͋ͬͨ৔߹ͷΈαʔόͱҰகͤ͞ΔΑ͏ʹಉظ͕ߦΘΕΔॲཧͰ͢ɻPrediction Λ͢ Δ໨త͸ɺΫϥΠΞϯτͷೖྗʹରͯ͠ɺαʔό͔ΒͷԠ౴Λ଴ͭͷͰ͸ͳ͘ɺΫϥΠΞϯτ͸ͦͷ ··ॲཧΛߦ͏͜ͱͰɺೖྗͷ଴ͪ࣌ؒΛ୹ॖͰ͖ΔΑ͏ʹ͢Δ͜ͱͰ͢ɻαʔό͸ 30FPS ͷ଎౓ ͰԋࢉΛߦ͍·͕͢ɺTick Λ༻͍ͯΫϥΠΞϯτ͸݁ՌΛಉظͤ͞·͢ɻ   ˙ϝϞ: ΋ͬͱৄ͘͠஌Γ͍ͨਓ΁ GDC Overwatch Gameplay Architecture and NetCodea Ͱ͸ɺECS ΍ NetCode Λ࢖ͬͨઃ ܭʹ͍ͭͯ Overwatch ͷ࣮ྫʹ஌Δ͜ͱ͕Ͱ͖ͱͯ΋ࢀߟʹͳΓ·͢ɻ ·ͨɺDeep dive into networking for Unity’s FPS Sample gamebͰ͸ɺNetCode ʹ͍ͭͯΑ Γৄࡉʹ஌Δ͜ͱ͕Ͱ͖·͢ɻ a https://www.youtube.com/watch?v=W3aieHjyNvw b https://www.youtube.com/watch?v=k6JTaFE7SYI   5.7 Unity Physics Unity Physics*8͸ DOTS ͷͨΊʹ৽͘͠ C#Ͱॻ͔Εͨ෺ཧԋࢉͷύοέʔδͰɺDOTS Ͱ࣮ߦ ͢Δ͜ͱͰύϑΥʔϚϯε͕޲্͍ͯ͠·͢ɻલड़ͷ Unity NetCode Ͱ΋༻͍Δ͜ͱ͕Ͱ͖·͢ɻ ·ͨɺ಺෦ॲཧΛ Havok Physics ʹ੾Γସ͑Δ͜ͱ΋ՄೳͰ͢ɻ CharacterController ͷ࣮૷ kinematic Λϕʔεͱͨ͠ Character Controller ͷ࣮૷ͷҰྫΛ঺հ͠·͢ɻ֤ॲཧΛ Job ͱ͠ ͯඇಉظͰ࣮ߦ͢Δ͜ͱʹΑΓɺύϑΥʔϚϯε͕޲্͠·͢ɻΞʔΩλΠϓʹΑΔνϟϯΫʹΑͬ ͯ·ͱΊͯॲཧΛߦ͏ͨΊɺIJobChunk Λ࢖༻͠·͢ɻνϟϯΫ͝ͱʹ࣍ͷ֤ॲཧΛߦ͍·͢ɻ *8 https://docs.unity3d.com/Packages/[email protected]/manual/index.html 48
  48. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.8 Data Flow Graph

    • ઀஍͍ͯ͠Δ͔ͷ൑ఆɺॏྗͷՃࢉɺδϟϯϓͷॲཧ • ਫฏҠಈɺஈࠩͷিಥ൑ఆɺҠಈͳͲ • ϓϨΠϠʔίϯτϩʔϧ 5.8 Data Flow Graph DOTS Ͱॲཧͷ࣮ߦॱΛදݱ͢ΔΑ͏ͳखஈͱͯ͠ Data Flow Graph*9ʢҎԼ DFGʣ͕͋Γ· ͢ɻ࣮ߦॱ͸άϥϑͷΑ͏ͳ໰୊ʹந৅ԽͰ͖ɺUnity ͸͜ͷ໨తͷͨΊʹ௿ϨϕϧύοέʔδΛ։ ൃ͍ͯ͠·͢ɻ·ͣಛ௃ͱͯ͠͸ɺ༗޲άϥϑͷσʔλߏ଄Λఆٛ͠ɺNode ͔Β Edgeʢ઀ଓʣΛ ࢖ͬͯσʔλͷૹ৴Λߦ͍ɺNode ʹఆٛ͞Εͨؔ਺Λ࣮ߦ͠·͢ɻ͜ΕΒͷॲཧ͸ΦʔσΟΦʹ͓ ͚ΔϑΟϧλॲཧ (IIRɺDSP)ɺAnimation Ͱ༻͍Δ͜ͱ͕Ͱ͖·͢ɻ Node NodeSet ʹରͯ͠ Node Λ࡞੒͠௥Ճ͠·͢ɻNode ͸࣍ͷ΋ͷΛ࣋ͪ·͢ɻ Portʢϝοηʔδͷೖྗઌɺग़ྗޱʣ • MessageInput – ϝοηʔδͷೖྗΛఆٛ • MessageOutput – ϝοηʔδͷग़ྗΛఆٛ DataʢϝοηʔδΛॲཧ͢Δʣ ఆٛ͞Εͨܕ͝ͱʹ Message Handler Λ࣮૷͠·͢ɻϝοηʔδ͸ܕ͝ͱʹɺ ఆٛ͞Εͨ Message Handler Ͱॲཧ͞Εɺෳ਺ೖྗ͕͋ͬͨ৔߹͸ͦͷ౎౓࣮ߦ͞Ε·͢ɻϝοηʔδ͸ Data ಺ͷม਺ ʹ֨ೲ͓ͯ͘͜͠ͱ͕Ͱ͖·͢ɻ • EmitMessage API – ग़ྗͱͯ͠ઃఆͨ͠ Port(MessageOutput) ʹ઀ଓ͍ͯ͠Δ΄͔ Node ͷ Port ͢΂ͯʹ ରͯ͠ϝοηʔδΛૹ৴͢Δɻ • Connect API – ૹ৴ݩ Nodeɺ ૹ৴ݩ Portɺ Ѽઌ Nodeɺ Ѽઌ Port Λࢦఆ͢Δ͜ͱͰάϥϑΛ઀ଓͰ͖Δɻ • SendMessage – ϝοηʔδΛ࣮ࡍʹૹ৴Ͱ͖Δɻ *9 https://docs.unity3d.com/Packages/com.unity.datafl[email protected]/manual/index.html 49
  49. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.9 Animation • Update

    – RegisterForUpdate Λݺͼग़͢͜ͱͰɺఆظతʹ IUpdate.Update ؔ਺Λ࣮ߦͰ͖Δɻ ࣮ߦλΠϛϯά ࣮ߦ͞ΕΔλΠϛϯά͸ɺγϛϡϨʔγϣϯͱϨϯμϦϯάʹ෼͔Ε͓ͯΓɺγϛϡϨʔγϣϯ͸ ओʹɺNode ͷ࡞੒΍઀ଓɺߋ৽ɺ"ϝοηʔδ"ͷૹ৴ͳͲΛߦ͍ɺϨϯμϦϯάϑΣʔζͰ࣮ࡍͷ ॲཧΛߦ͍·͢ɻ͜Ε͸௨ৗ NodeSet ຖʹඇಉظͰߦΘΕ·͢ɻ Kernel Data Flows ϨϯμϦϯά࣌ʹ༻͍ΒΕΔɺσʔλೖྗ/ग़ྗؒͷ઀ଓϙΠϯτͰɺγϛϡϨʔγϣϯͰ͸ϝο ηʔδΛ༻͍ͯ௨৴͠·͕ͨ͠ɺϨϯμϦϯάͰ͸ Kernel Port(DataInputɺDataOutput) Λ༻͍ ͯ௨৴͠·͢ɻIKernelData ͰύϥϝʔλʢεΧϥ஋ɺ഑ྻɺߏ଄ମͳͲʣΛఆٛ͠ɺ઀ଓ͞Εͨ Node ͷτϙϩδΧϧιʔτΛߦ͔ͬͯΒ IGraphKernel.Execute ͷॲཧ͕ࣗಈతʹ࣮ߦ͞Ε·͢ɻ γϛϡϨʔγϣϯͷϊʔυఆٛͱϨϯμϦϯάͰͷϊʔυఆٛ (KernelDefs) ͸྆ํಉ࣌ʹ࢖͏͜ͱ ΋Ͱ͖·͢ɻγϛϡϨʔλʔ͔ΒϨϯμϦϯά΁ͷߋ৽͸ߦ͏͜ͱ͕Ͱ͖·͕͢ɺٯ͸ෆՄͰ͢ɻ 5.9 Animation ্ه DFG Λ༻͍ͯɺDOTS Ͱͷ Animation ʹ͍ͭͯ৮Ε͍͖ͯ·͢ɻ DOTS ͷ Animation ύοέʔδ Animation ύοέʔδ*10͸ Unity Animation Rigging ͷػೳΛ༻͍͓ͯΓɺݱࡏ͸ HDRP(High Definition Render Pipeline) ͱ URP(Universal Render Pipeline) ʹରԠ͍ͯ͠·͢ɻUnity Ani- mation Rigging ͸ಈతͳϞʔγϣϯੜ੒ʢRiggingʣΛ໨తͱͨ͠ύοέʔδͰ͢ɻ۩ମతͳαϯ ϓϧ͸ Unity.Animation.Samples*11ʹࣔ͞Ε͍ͯ·͢ɻಛ௃ͱͯ͠ɺैདྷͷΑ͏ͳ Animator ͸ ࢖ΘͣʹɺAnimation Graph Λ࢖༻ͯ͠ΞχϝʔγϣϯΛ੍ޚ͠·͢ɻΞχϝʔγϣϯ͸ Rig ͱ Animation Clip Λ༻͍ͯɺGraph ͸Ξχϝʔγϣϯ͝ͱʹ࡞੒͠·͢ɻ্هγεςϜͰ͸ɺγϛϡ Ϩʔγϣϯ࣌ʹ͸࣮ࡍͷΞχϝʔγϣϯͷܭࢉ͸ߦΘͣɺϨϯμϦϯά࣌ʹߦ͍·͢ɻ Animation Graph Animation Graph Λ࡞੒ํ๏͸جຊతʹ͸ DFG ͰɺNode ʹΞχϝʔγϣϯؔ܎ͷॲཧ͕·ͱ ΊΒΕ͍ͯ·͢ɻ۩ମతʹΞχϝʔγϣϯͷॲཧ͸ ClipPlayerNode Ͱߦ͍·͢ɻجຊతͳΞχϝʔ γϣϯͷྲྀΕ͸ҎԼͷΑ͏ʹͳΓ·͢ɻ *10 https://docs.unity3d.com/Packages/[email protected]/manual/index.html *11 https://github.com/Unity-Technologies/Unity.Animation.Samples 50
  50. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.9 Animation  

    DeltaTimeNode ˠ ClipPlayerNode ˠ ComponentNode   DeltaTimeNode ͔ΒΞχϝʔγϣϯͷ࠶ੜϑϨʔϜ͕࣌ؒ ClipPlayerNode ʹ౉͞Εɺ Ξχϝʔγ ϣϯͷॲཧ͕ߦΘΕͨޙɺ ݁Ռ͕ ComponentNode ʹ౉͞ΕΔΑ͏ͳྲྀΕͰ͢ɻComponentNode ͸ Clip ͱ Rig Λ࣋ͭ Entity ͱͷඥ෇͚Λߦ͍·͢ɻ·ͨɺ Graph ͸ ProcessDefaultAnimationGraph ͱ͍͏ System Ͱ؅ཧ͍ͯͯ͠ɺAddRef() Λݺͼग़ͯ͠࢖༻͢Δ͜ͱΛ໌ࣔ͠ɺGraph Λ࡞੒͠ ·͢ɻ ClipPlayerNode ʹඞཁͳ΋ͷ Simulation Ports • Clip – ECS ͔Βࢀর͢ΔͨΊɺAnimation Clip Λ BlobAssetStore ʹม׵ͨ͠΋ͷ • Rig – Rig(Unity Animation Rigging) ΛɺECS Ͱ༻͍ΔͨΊ BlobAssetReference ʹม׵ͨ͠ ΋ͷ • Configuration – ΞχϝʔγϣϯͷઃఆʢMotion ID ΍ϧʔϓઃఆͳͲʣ KernelPorts • Speed – Ξχϝʔγϣϯͷ࠶ੜεϐʔυ • DeltaTime – Ξχϝʔγϣϯͷ࠶ੜϑϨʔϜ࣌ؒ Animation Stream ࠷ऴతʹ KernelPorts.Output Λ ComponentNode ઀ଓ͠ɺOutput ͷ AnimatedData Buffer Λ ComponentNode ʹ౉͢͜ͱͰɺΞχϝʔγϣϯΛ࠶ੜͰ͖·͢ɻ͜ͷҰ࿈ͷྲྀΕΛ Animation Stream ͱݺͼ·͢ɻ࢒೦ͳ͕ΒݱࡏΫϩʔζυͰ։ൃ͞Ε͍ͯΔͨΊɺ֤ϊʔυͰ۩ମతʹͲΜͳ ॲཧΛ͍ͯ͠Δͷ͔֬ೝ͢Δ͢΂͸͋Γ·ͤΜɻ ·ͱΊ DOTS ͷ Animation ͸ Animation Graph Λ࢖੍ͬͯޚ͢Δ͜ͱΛݟ͖ͯ·ͨ͠ɻϘʔϯϨϯμ Ϧϯά΍ΞχϝʔγϣϯͷϒϨϯυͳͲ΋ɺGraph ͷߏ଄ɺNode ΛมԽͤ͞Δ͜ͱʹΑͬͯߦ͑ 51
  51. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.10 Build ·͢ɻ ଞʹ΋

    RigRemapperNode Λ༻͍Δ͜ͱͰ Animation Stream Λ΄͔ͷ Rig ߏ଄Λ࣋ͭ Anima- tion Stream ʹ࠶Ϛοϐϯά͢Δػೳ΋ଘࡏ͠·͢ɻ·ͨɺ͞·͟·ͳ Rig Constraints Λ༻͍Δ͜ ͱͰɺݱࡏͷ MecanimʢAnimatorʣͰ͸࣮ݱ͕೉͍͠ػೳ΋࣮૷͕Ͱ͖·͢ɻ ʢex. IKɺεΩϯ΢Σ ΠτɺΦϒδΣΫτΛ࣋ͭͳͲʣ   ˙ϝϞ: Unity ͷ Roadmap Unity Roadmap 2020aͰ͸ɺ͜ͷ Animation ʹؔ͢Δπʔϧྨͷ௥Ճ΍ɺTimeline ΍ Kine- matica ͳͲ΋ DOTS ͱͯ͠௥Ճ͞ΕΔ͜ͱ͕ࣔࠦ͞Ε͓ͯΓɺࠓޙͷಈ޲͔Β໨͕཭ͤ· ͤΜɻ a https://www.youtube.com/watch?t=1012&v=dDjsS4NPqFU   5.10 Build DOTS ͰͷϏϧυʹ͍ͭͯ঺հ͠·͢ɻ Scriptable Build Pipeline DOTS Ͱ͸ Unity ͷඪ४ͷ Build ํ๏Ͱ͸ͳ͘ Scriptable Build Pipeline Λ༻͍·͢ɻ͜Ε͸ ϏϧυύΠϓϥΠϯΛ C#ͷύοέʔδΛ༻͍ͯهड़Ͱ͖Δ΋ͷͰɺBuildConfiguration ͱ͍͏Ξ ηοτΛ༻͍ͯఆٛ͠·͢ɻσόΠε΍ΫϥΠΞϯτɺαʔόʹԠͯ͡ɺରԠ͢ΔϏϧυύΠϓϥΠ ϯΛఆٛͨ͠ΓɺಠࣗͷϏϧυύΠϓϥΠϯΛఆٛͨ͠ΓͰ͖·͢ɻϏϧυύΠϓϥΠϯ͸ɺผͷ BuildConfiguration ͔ΒઃఆΛܧঝͰ͖·͢ɻ Platforms DOTS ʹ͓͚ΔϏϧυϓϥοτϑΥʔϜͱϏϧυ API ͷج൫Λఏڙ͢Δ΋ͷͰɺσόΠεʹରԠ ͢Δ΄͔ͷ Platforms ύοέʔδ͕ଘࡏ͠·͢ɻ • Linux • Mac • Windows • Android, IOS • Web 52
  52. ୈ 5 ষ Unity DOTS ׬શ߈ུΨΠυ 5.11 ऴΘΓʹ Headless Build

    ίϯιʔϧΞϓϦέʔγϣϯͱͯ͠ɺελϯυΞϩʔϯϏϧυΛ࡞੒Ͱ͖ΔઃఆͰ͢ɻNetCode Λ༻͍ͨ৔߹ɺ͜ΕʹΑΓαʔό࣮ߦόΠφϦΛϏϧυͰ͖·͢ɻ ਤ 5.2: Headless Build ͷઃఆαϯϓϧ 5.11 ऴΘΓʹ Unity DOTS ͷ֤ٕज़ʹ͍֤ٕͭͯज़ͷ֓ཁʹ͍ͭͯݟ͖ͯ·ͨ͠ɻຊষʹ͸ॻ͖͖Ε·ͤΜͰ ͕ͨ͠ɺ͞·͟·ͳ৘ใΛ·ͱΊͯମܥతʹཧղͰ͖ΔΑ͏ʹͨͭ͠΋ΓͰ͢ɻσʔλࢦ޲ઃܭͱ͍ ͏ CPU ར༻཰Λ࠷େݶߴΊΔऔΓ૊Έ΍ɺECS ͱ͍ͬͨൺֱతΘ͔Γ΍͍͢ઃܭʹΑͬͯ DOTS ʹ͸ར༻͢ΔՄೳੑ͕͋Δͱײ͍ͯ͡·͢ɻҰํͰɺΦϒδΣΫτࢦ޲ʹ׳ΕͨϓϩάϥϚʔʹ͸ଟ গ෼͔ΓͮΒ͍఺΋͋Γɺ׳ΕΔ·Ͱͷ͕࣌ؒඞཁͩͱࢥ͍·͢ɻ·ͨ DOTS ͷଟ͘ͷٕज़͸ݱࡏ Preview ൛Ͱ಺༰͕େ͖͘มߋ͞ΕΔڪΕ͕͋Γ·͕͢ɺͦͷล͸ྃ͝ঝ͍ͩ͘͞ɻ 53
  53. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺ ಧ͍ͯ·͔͢ʁ ʙ 6.1 ࢝Ίʹ ຊষͰ͸ɺ೔͝ΖɺDevRel

    ͱ͍͏ཱ৔Ͱࣾ಺ΤϯδχΞͷΞ΢τϓοτΛαϙʔτ͍ͯ͠Δචऀ ͕ߟ͑Δɺಧ͚͍ͨਓʹ͖ͪΜͱಧ͚ΔͨΊͷΞ΢τϓοτज़ʹ͍ͭͯॻ͍͍͖ͯ·͢ɻ ૝ఆಡऀ ຊষͷ૝ఆಡऀ͸ɺҰൠతͳιϑτ΢ΣΞ։ൃΛ୲͍ͬͯΔٕज़৬ͷํΛର৅ͱ͍ͯ͠·͢ɻಛ ʹɺΞ΢τϓοτͯ͠Έ͍ͨͱࢥ͍ͬͯΔ͚Ͳͳ͔ͳ͔౿ΈࠐΊͳ͍Ͱ͍ΔɺΞ΢τϓοτ͍ͯ͠Δ ͚Ͳ͍·ͻͱͭࣗ৴͕ͳ͍ͱ͍ͬͨํ޲͚ͷ಺༰ͱͳ͍ͬͯ·͢ɻ ॻ͘͜ͱ • ։ൃۀ຿಺΍ݸਓతͳݚڀɾௐࠪͷதͰಘٕͨज़஌ݟͷΞ΢τϓοτʹ͍ͭͯ ॻ͔ͳ͍͜ͱ • ։ൃऀ޲͚ϚʔέςΟϯάʹؔ͢Δ࿩ • ֦ࢄͤ͞Δ͜ͱ͕ૂ͍ͷΞ΢τϓοτʹؔͯ͠ ͳ͓ɺ৘ใΛൃ৴͢Δ৔ॴ΍ɺυΩϡϝϯτͩͬͨΓɺϓϨθϯςʔγϣϯͩͬͨΓͷදݱํ๏͸ ݶఆ͠·ͤΜɻࣾ಺޲͚ɺࣾ֎޲͚ͳͷ͔΋໰͍·ͤΜɻ ·ͨɺචऀࣗ਎΋ϥΠςΟϯά΍ϓϨθϯςʔγϣϯͷϓϩͰ͸ͳ͍ͷͰɺͥͻօ͞Μͷ͝ҙݟ΍ ͝ײ૝΋ฉ͔͍ͤͯͩ͘͞ɻຊষΛಡΜͰɺ͜͜͸͜͏ͨ͠΄͏͕Α͍Αͱ͔ɺ͜͏͍͏ߟ͑ํ΋͋ ΔΑͱ͔ɺTwitter ΍ϒϩάͳͲͰڞ༗͍͚ͯͨͩ͠Δͱ͏Ε͍͠Ͱ͢ɻ ʮ#ٕज़ॻయʯΛ͚͍ͭͯͨ ͚ͩΔͱͳ͓͏Ε͍͠Ͱ͢ɻ 55
  54. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.2 ஌ݟͷΦʔϓϯԽͷ࣌୅ 6.2 ஌ݟͷΦʔϓϯԽͷ࣌୅

    ࠷ۙͰ͸ɺIT ܥαʔϏε΍੡඼Λ։ൃ͢Δاۀʹॴଐ͍ͯ͠Διϑτ΢ΣΞɾΤϯδχΞͰ͋Ε ͹ɺԿ͔͠ΒͷΞ΢τϓοτͷػձ͕͋Δ͔ͱࢥ͍·͢ɻࣾ಺Ͱ͋Ε͹ɺࣾ಺ษڧձ΍ࣾ಺޲͚৘ใ ڞ༗πʔϧɺࣾ֎Ͱ͋Ε͹ɺ࠾༻ਓࣄ΍্͔࢘Βཔ·ΕͯΠϕϯτʹొஃͨ͠ΓɺΤϯδχΞɾϒϩ άͰ࠷ۙͷऔΓ૊ΈΛॻ͍ͯΈͨͳͲɺΤϯδχΞʹΑΔΞ΢τϓοτ͕౰ͨΓલͷΑ͏ʹߦΘΕͯ ͍·͢ɻ ʻΤϯδχΞͷΞ΢τϓοτػձʼ • ࣾ಺޲͚ – ࣾ಺ษڧձ – ࣾ಺޲͚৘ใڞ༗πʔϧ • ࣾ֎޲͚ – ΤϯδχΞɾϒϩά – GitHub ΍ SlideShare ͳͲͷυΩϡϝϯτڞ༗πʔϧ – ษڧձ΍ΠϕϯτͰͷߨԋ (ΦϯϥΠϯɺΦϑϥΠϯ) – Twitter ͳͲͷ SNS ΁ͷ౤ߘ – ॻ੶ࣥච – ϝσΟΞ΁ͷدߘ΍ΠϯλϏϡʔ ੲ͸ɺاۀ͕੡඼ʹ࠾༻͞Ε͍ͯΔٕज़ʹ͍ͭͯɺڝ߹ଞࣾ΋͍Δެڞͷ৔Ͱٕज़ऀࣗ਎͕ޠΔ͜ ͱ͸Ίͬͨʹ͋Γ·ͤΜͰͨ͠ɻͰ͸ɺͳͥ࠷ۙͷاۀ΍ٕज़ऀୡ͸ɺٕज़஌ݟ΍ϊ΢ϋ΢Λެ։͢ ΔΑ͏ʹͳͬͨͷͰ͠ΐ͏͔ʁ ݸਓʹΑΔϒϩά΍ Twitter ౳ͷ SNS ͕Ұൠతʹͳ͖ͬͯͨݱࡏͰ͸ɺ झຯ͚ͩͰͳ͘ϓϩϑΣο γϣφϧͱͯ͠ݸਓͷັྗΛ఻͑ΔηϧϑɾϒϥϯσΟϯά͕౰ͨΓલʹͳ͍ͬͯͨΓɺࣗݾݚຏ΋ ैདྷͷݚम΍ηϛφʔͱ͍ͬͨձࣾͰ༻ҙ͞ΕͨϓϩάϥϜʹཔΔͷͰ͸ͳ͘ɺੈքதͷ։ൃऀ΍ݚ ڀऀ͔Βͷ৘ใ͕ू·ΔΠϯλʔωοτ্ͰֶͼΛಘͨΓͱɺΠϯλʔωοτͷීٴͱͱ΋ʹݸਓత ͳҙݟ΍·ͱΊΛΦʔϓϯʹ͢Δ͜ͱʹ΋఍߅͕ͳ͘ͳ͖ͬͯͨͷͰ͸ͳ͍͔ͱࢥ͍·͢ɻͦΕͱ ಉ࣌ʹɺੲ͸Ұ෦ͷٕज़ऀͷ΋ͷͩͬͨΑ͏ͳ OSS ίϛϡχςΟ΁ͷҰൠͷํͷࢀՃϋʔυϧ΋Լ ͕͍ͬͯΔͳͲɺΦʔϓϯͳ৔Ͱ৘ใΛڞ༗ٞ͠࿦͢Δ͜ͱͰɺҰॹʹͳͬͯ੒௕͠ڞ૑͕Ͱ͖Δ؀ ڥ΋੔͖͍ͬͯͯ·͢ɻ৔ॴ΍࣌ؒΛબ͹ͣɺݸਓ͕ؾܰʹ৘ใΛൃ৴ͨ͠ΓಘΔ͜ͱ͕Ͱ͖ΔΑ͏ ʹͳͬͨࠓɺηϧϑϒϥϯσΟϯά͚ͩͰͳ͘ɺࣗݾݚຏ΍ྗࢼ͠ͷ৔ͱͯ͠΋ͦ͏͍ͬͨΞ΢τ ϓοτͷػձΛ׆༻͍ͯ͠Δέʔε΋ΈΒΕ·͢ɻ ·ͨɺاۀ͕ݱ৔Ͱಇٕ͘ज़ऀͳͲʹɺެࣜϒϩά΍֎෦ΠϕϯτͰͷߨԋΛґཔ͢Δओͳૂ͍ͱ ͯ͠͸ɺ࠾༻໘͔Βͷظ଴͕Ұ൪ͳͷͰ͸ͳ͍Ͱ͠ΐ͏͔ɻಛʹΤϯδχΞ࠾༻͸೥ʑ೉͘͠ͳͬͯ ͖͓ͯΓɺചΓखࢢ৔ͱͳͬͨࠓͰ͸ଞࣾͱͷࠩผԽ͕ٸ຿ͱͳ͍ͬͯͨΓɺ࠾༻ཁ݅΋อ༗͢Δε Ωϧ͚ͩͰͳ͘ɺީิऀͱνʔϜͱͷ૬ੑ΍ΧϧνϟʔϚονͳͲ΋ॏཁࢹ͞ΕΔΑ͏ʹͳ͖ͬͯ· 56
  55. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.3 ୭΋͕௨Δ࢒೦ମݧ ͨ͠ɻ୯ʹັྗతͳ৚݅Λฒ΂ͨٻਓ޿ࠂΛస৬αΠτʹܝࡌ͢Ε͹Α͍͚ͩͷ࣌୅͸ऴΘΓɺΤϯ δχΞจԽ΍ͦͷձࣾͰಇ͘͜ͱͷັྗΛ఻͑ΔͨΊͷ࠾༻ϚʔέςΟϯά͕ඞਢͱͳ͖͍ͬͯͯ·

    ͢ɻͦͷ΄͔ɺՈిϝʔΧʔͳͲͰߦΘΕ͍ͯΔैདྷͷٕज़޿ใͱ͍͏ଆ໘ͰɺͦͷϓϩμΫτ͕ߴ ͍ٕज़ྗͰੜ·Ε͍ͯΔ͜ͱΛ఻͑ɺIT ੡඼ͱͯ͠ͷϨϕϧͷߴ͞Λ঎඼ͷϒϥϯυͱͯ͠ૌٻ͢ Δ໨తͰ΋ߦΘΕ͍ͯͨΓ΋͠·͢ɻ ʻٕज़ऀʹΑΔΞ΢τϓοτͷૂ͍΍ಈػʼ • اۀ – ࠾༻ϚʔέςΟϯά – ίʔϙϨʔτ޿ใɾٕज़޿ใ – OSS ͳͲ΁ͷߩݙɺCSRɺ౳ • ݸਓ – ηϧϑɾϒϥϯσΟϯά – ݸਓతͳϝϞͱͯ͠ – ୈࡾऀ͔ΒͷΞυόΠε΍஌ݟΛಘΔͨΊ – ٕज़ऀͱͯ͠ͷ௅ઓ – ࣾձߩݙɺ౳ ࠷ۙͰ͸ɺٕज़ίϛϡχςΟͷ׆ಈ΋ඇৗʹ׆ൃͰɺͦ͏͍ͬͨ৔Ͱͷͭͳ͕Γ͔Β৽ͨͳٕज़ νϟϨϯδʹͭͳ͕ͬͨΓɺ࣍ͷΩϟϦΞ΁ͱͭͳ͕ͬͨΓ͢ΔՄೳੑ΋͋Γɺاۀʹͱͬͯ΋ݸਓ ʹͱͬͯ΋৽͍͠ίϥϘϨʔγϣϯͷػձ͕͋Γ·͢ɻ 6.3 ୭΋͕௨Δ࢒೦ମݧ Ξ΢τϓοτ͸౒ྗͷࣀ෺ Ξ΢τϓοτ͸ීஈͷٕज़ऀͱͯ͠ͷ׆ಈͷ੒ՌͰ΋͋Γ·͢ɻ໨·͙Δ͘͠มԽ͢Δٕज़΍ࢢ৔ χʔζͱ޲͖߹͍ɺ࣮ϓϩμΫτʹ࣮૷͞Εٕͨज़΍ϊ΢ϋ΢͸ɺࠣࡉͳ޻෉Ͱ͋ͬͨͱͯ͠΋΄͔ ͷٕज़ऀʹͱͬͯ͸وॏͳࢀߟࢿྉʹ΋ͳΓ͑·͢ɻ ·ͨɺٕज़తͳ஌ݟ΍ٕज़ऀͱͯ͠ͷମݧΛΞ΢τϓοτ͢Δͦͷഎܠ΍ཧ༝͸ͦΕͧΕͰ͕͢ɺ ͓ͦΒ͘͢΂ͯͷέʔεʹ͓͍ͯɺͦͷΞ΢τϓοτʹର͢Δ୭͔ͷϙδςΟϒͳϑΟʔυόοΫΛ ಘΔͨΊʹਅ݋ʹίϯςϯπͷݕ౼Λ͘Γฦ͠ɺͦΕͳΓͷ࣌ؒΛ͔͚ͯ४උΛਐΊΒΕ͍ͯΔ΋ͷ ͩͱࢥ͍·͢ɻ ͦ͏ͯ͠·ͱΊΒΕͨΞ΢τϓοτ͸ɺΤϯδχΞࣗ਎ͷ೔ʑͷ࿑ྗͱۤ೉ͷ݁Ռ͕٧·ͬͨ౒ྗ ͷࣀ෺ͳͷͰ͢ɻ 57
  56. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.4 ஌ݟΛಧ͚Δٕज़ ظ଴ͯ͠͸͍͚ͳ͍࢝ΊͷҰา Ξ΢τϓοτ͞Εͨ৘ใ͸ɺ࠷ॳʹΧϯϑΝϨϯεͳͲͰͷௌߨऀ΍पลͷ༑ਓɾ஌ਓɺTwitter

    ͷϑΥϩϫʔͳͲʹ఻ΘΓɺͦΕΒͷड͚ख͕ͦͷ಺༰ʹ৺͕ಈ͔͞ΕΔ͜ͱͰɺ͞Βʹͦͷͭͳ͕ Γʹ఻ΘΔͱ͍͏;͏ʹ೾໲ͷΑ͏ʹ޿͕͍͖ͬͯ·͢ɻ ਤ 6.1: Ξ΢τϓοτͷӨڹྗ ͔͠͠ͳ͕Βɺແ໊ͷҰൠਓʹͱͬͯ͸ɺ͜ͷ͖Ε͍ͳ೾໲Λ࢝ΊͷҰาͰඳ͘ͷ͸ͳ͔ͳ͔೉͠ ͍ͷ͕ݱ࣮Ͱ͢ɻஶ໊ਓͱҟͳΓɺௌߨऀͳͲͷ௚઀తͳͭͳ͕Γͷ਺͕গͳ͘ɺ࿩୊ʹ΋ͳΓʹ͘ ͍ͷͰӨڹྗ͕ऑ͘޿ൣғ΁ͷ೾ٴ΋ऑ͘ͳΓ·͢ɻͰ͸ɺͲ͏͢Ε͹ྑ͍ͷͰ͠ΐ͏͔ʁ Ұੜݒ ໋४උΛͯࣗ͠৴ຬʑͰ৘ใൃ৴Λͨ͠ͱ͍͏ͷʹɺ૬खͷ൓Ԡ͕͍·ͻͱͭͩͬͨͱ͍͏ܦݧ͸͋ Γ·ͤΜ͔ʁ Կ͕ѱ͔ͬͨͷ͔Θ͔ΒͣʹɺϞϠϞϠͨ͠ͱ͍͏ํ΋গͳ͘ͳ͍ͷͰ͸ͳ͍Ͱ͠ΐ ͏͔ɻ࣍ʹɺҰൠͷΤϯδχΞ͕Ξ΢τϓοτΛ͢Δࡍɺظ଴௨Γͷ݁ՌΛग़ͨ͢ΊʹؾΛ෇͚Δ΂ ͖ϙΠϯτΛॏཁͳ΋ͷʹߜͬͯ঺հ͍͖ͯ͠·͢ɻ 6.4 ஌ݟΛಧ͚Δٕज़ ͳΜͱͳ͘༑ਓʹקΊΒΕͨຊΛಡΜͰ͍ͨΒɺ͍ͭͷؒʹ͔Ҿ͖ࠐ·Εͯ͋ͬͱ͍͏ؒʹಡΈ ੾ͬͯ͠·ͬͨͱ͍͏ܦݧ͸͋Γ·ͤΜ͔ʁ ٯʹɺςʔϚ͸͓΋͠Ζͦ͏ͳͷʹɺͳ͔ͥ຾͘ͳͬ ͯ͠·ͬͨߨԋ͸͋Γ·ͤΜͰ͔ͨ͠ʁ ͦͷ఻͑ํҰͭͰɺͦͷΞ΢τϓοτͷ૬ख΁ͷಧ͖ํ΋ มΘͬͯ͘ΔͷͰ͢ɻ ͜͜Ͱ͸ɺ஌ݟΛ͖ͪΜͱૂ͍௨Γʹ఻͑ΔͨΊͷνΣοΫϙΠϯτΛɺ ʮاըϑΣʔζʯͱʮද ݱϑΣʔζʯʹ෼͚ͯઆ໌͍͖͍ͯͨ͠ͱࢥ͍·͢ɻ 58
  57. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.4 ஌ݟΛಧ͚Δٕज़ ਤ 6.2:

    ஌ݟΛ఻͑ΔͨΊͷνΣοΫϙΠϯτ اըϑΣʔζ ·ͣൃදࢿྉ΍ϒϩάΛॻ͖࢝ΊΔલʹɺΞ΢τϓοτͷΞ΢τϥΠϯΛܾΊ·͢ɻ୭ʹԿΛԿͷ ͨΊʹͲ͏΍ͬͯΞ΢τϓοτ͢Δͷ͔ɻͦͷ࣌ؒͷֻ͚ํ͸దٓͰྑ͍ͱࢥ͍·͕͢ɺԿ͔·ͱ ·ͬͨࣄฑΛ࿩୊ͱͯ͠·ͱΊͯୈࡾऀʹڞ༗͢Δࡍɺ͋Β͔͡Ί֓ཁΛ੔ཧ͓ͯ͘͜͠ͱΛश׳Խ ͢ΔͱΞ΢τϓοτ΋্ୡ͍ͯ͘͠ͷͰ͸ͳ͍͔ͱࢥ͍·͢ɻ ৽͍͠ςʔϚΛߟ͑Δ ϓϩμΫτ։ൃͷݱ৔Ͱ׆༂͢ΔΤϯδχΞ͕ɺٕज़తͳ஌ݟ΍։ൃϊ΢ϋ΢Λ୭͔ʹڞ༗͢Δ ࣌ɺςʔϚͱͯ͠͸ҎԼͷΑ͏ͳ΋ͷ͕͋͛ΒΕΔ͔ͱࢥ͍·͢ɻ • ຊ൪؀ڥʹ৽͍͠Ϋϥ΢υαʔϏεΛಋೖͨ͠࿩ • γεςϜͷύϑΥʔϚϯεΛ˓ˋվળͨ͠࿩ • ˓˓ͷ։ൃͰϋϚͬͨͱ͖ͷղܾํ๏ ͜ΕΒʹڞ௨͢Δͷ͸ɺड͚औΔ૬खʹͱͬͯʮ৽͍͠ʯͱ͍͏͜ͱͰ͢ɻվળܥͷ࿩͕৽͍͠ͱ ͍͏͜ͱʹٙ໰Λײ͡Δ͔΋͠Ε·ͤΜ͕ɺ৽͍ٕ͠ज़΍αʔϏεʹݶΒͣɺγεςϜͷύϑΥʔϚ ϯεΛվળͨ͠ࡍͷண؟఺΍ൃ૝ɺ໰୊ղܾʹ޲͔͏·ͰͷϓϩηεͳͲɺ૬खʹͱͬͯ͜Ε·Ͱܦ ݧͨ͜͠ͱͷͳ͍ʮ৽͍͠ʯԿ͔͕͋Δ͜ͱͰɺͦͷΞ΢τϓοτ͸Ձ஋͋Δ΋ͷʹมΘΓ·͢ɻ ͱ͸͍͑ݱ࣮͸ɺطଘϓϩμΫτͷ։ൃݱ৔ͳͲͰ͸ɺॗʑͱٕज़ෛ࠴Λղফͨ͠Γɺͪΐͬͱ͠ ͨػೳվम͕େ൒Ͱɺ ʮࣗ෼͸େͨ͜͠ͱ΍͍ͬͯͳ͍͠ʯ ʮಛʹਅ৽͍͜͠ͱ͸΍͍ͬͯͳ͍ʯͱߟ ͑Δํ΋ଟ͍͔ͱࢥ͍·͢ɻͦ͏͍͏৔߹͸ɺݟΔ֯౓Λม͑ͯΈΔͷ΋Ұͭͷख͔ͱࢥ͍·͢ɻ੾ ΓޱΛม͑ͯΈΔ͜ͱͰɺ͍Ζ͍Ζͳݟ͑ํ͕ग़ͯ͘ΔͷͰ͸ͳ͍͔ͱࢥ͍·͢ɻ 59
  58. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.4 ஌ݟΛಧ͚Δٕज़ ໌֬ͳΰʔϧΛఆΊΔ ୭ʹରͯ͠ɺԿΛ࣋ͪؼͬͯ΋Β͍͍ͨͷ͔ͱ͍͏ɺΞ΢τϓοτͷ݁Ռͱͯ͠ͷΰʔϧΛɺ໌֬

    ʹఆΊ·͢ɻ͘͝౰ͨΓલͷ͜ͱͰɺ͢Ͱʹ࣮ફ͞Ε͍ͯΔ͜ͱ͔΋͠Ε·ͤΜɻ͔͠͠ɺҙ֎ͱΞ ΢τϓοτΛ૊ΈཱͯΔաఔͰɺ͍ͭͷؒʹ͔఻͔͑ͨͬͨ͜ͱ͕༗໹ແ໹ʹͳ͍ͬͯͨͱ͍͏ܦݧ ͸͋Γ·ͤΜ͔ʁ اըݕ౼ͷϑΣʔζͰ໌֬ͳΰʔϧΛఆΊɺ͔ͬ͠Γͱͨ࣠͠Λ͓࣋ͬͯ͘͜ͱͰɺදݱϑΣʔζ Ͱͷߏ੒΋૊Έཱͯ΍͘͢ɺλʔήοτʹదͨ͠ܗͰਖ਼͘͠఻ΘΔΞ΢τϓοτΛ࡞Δ͜ͱ͕Ͱ͖ ·͢ɻ ڞײϙΠϯτΛ࡞Δ গ͠େ͛͞Ͱ͕͢ɺΞ΢τϓοτ͸ʮײಈʯͯ͠΋Β͏͜ͱ͕େࣄͰ͢ɻ࣮ମݧͷࣦഊ͔Βֶ΂Δ ͜ͱ͕ଟ͍ͷͱಉ༷ʹɺ ʮΘ͔Δʂʯͱ͍ͬͨײ৘ʹΑͬͯ৺͕ಈ͖ɺܹࢗͱͳΓࣗ෼ࣄͱͯ͠ҹ৅ ਂ͘هԱͯ͠΋Β͑Δ͔ΒͰ͢ɻ ·ͨɺड͚खͷײ৘Λಈ͔͢͜ͱͰͦͷΞ΢τϓοτ͸ӨڹྗΛ࣋ͪɺҰ࣍ड͚खͷ஌ਓ΍༑ਓʹ ೾ٴ͠͞Βʹͦͷ஌ਓ΍༑ਓͷೋ࣍ϑΥϩϫʔ΁ͱ͍͏;͏ʹɺ͋ͳ͕ͨ༗໊ਓͰͳ͔ͬͨͱͯ͠΋ ΑΓଟ͘ͷਓʹ஌ݟΛಧ͚Δ͜ͱ͕Ͱ͖·͢ɻ ΰʔϧΛఆΊΔࡍʹɺλʔήοτ૾΋໌֬ʹͳ͍ͬͯΔ͔ͱࢥ͍·͢ɻλʔήοτͷ৺͕ಈ͘Α͏ ͳڞײϙΠϯτΛΞ΢τϓοτͷதʹؚΊΔ͜ͱͰɺ͔ͬ͠Γͱ఻ΘΔΞ΢τϓοτʹͳΓ·͢ɻͨ ͩ͠ɺڞײͷԡ͠෇͚ʹͳΒͳ͍Α͏஫ҙ͍ͨ͠΋ͷͰ͢ɻ දݱϑΣʔζ Ξ΢τϓοτͷ֓ཁ͕ݻ·͖ͬͯͨΒɺ࣍͸ɺͦΕΛ͍͔ʹදݱ͍͔ͯ͘͠Ͱ͢ɻपล͔Β͜Ε͸ εΰΠʂ ͱڧ͘শࢍ͞ΕΔΑ͏ͳ࣮૷ࣄྫΛςʔϚʹ͍ͯͨ͠ͱͯ͠΋ɺ·ͨɺͦͷ੒Ռʹରͯ͠ ͍͘Β೤͍ࢥ͍͕͋ͬͨͱͯ͠΋ɺͦͷදݱํ๏͕ѱ͔ͬͨΓͨ͠Βɺ͔ͤͬ͘ͷൃදͷػձΛಘͯ ΋఻͍͑ͨ͜ͱ͕ਖ਼͘͠఻ΘΒͳ͍Α͏ͳ൵͍͠ӡ໋ʹͳͬͯ͠·͍·͢ɻ ݴޠදݱʹ͍ͭͯ͸ɺιϑτ΢ΣΞͷੈքʹݶΒͣɺੈͷதʹ͸ηʔϧε΍ϚʔέςΟϯάͳͲಉ ༷ͷ՝୊Λ๊͑Δਓʑ͕͍ͯɺจষ΍ϓϨθϯςʔγϣϯज़ʹ͍ͭͯͷॻ੶΍ηϛφʔͳͲ΋ͨ͘͞ Μ͋Γ·͢ɻ͜͜Ͱ͸঺հ͖͠Εͳ͍ Tips ΋ଟ͘ɺͥͻɺͦΕΒ΋ࢀߟʹ͍͚ͯͨͩ͠Ε͹ͱࢥ͍ ·͢ɻ ඞਢཁૉΛؚΊΔ ͜Ε͚ͩ͸ɺ֤Ξ΢τϓοτͷதʹؚΊ͓͖͍ͯͨͱ͍͏ཁૉͰ͢ɻ • ࣗݾ঺հ – ·ͬͨ͘஌Βͳ͍ਓͨͪʹ޲͔ͬͯࣗ෼ͷߟ͑Λ఻͑Δͱ͖ɺ·ͣ͸ɺࣗ෼͕୭ͳͷ͔Λ ఻͑Δ͜ͱΛ๨Εͯ͸͍͚·ͤΜɻϒϩάͳͲ͸ɺϓϩϑΟʔϧཝ͕͋Δͱࢥ͏ͷͰɺͦ ͷΤϯτϦ಺Ͱॻ͘ඞཁ͸͋Γ·ͤΜ͕ɺߨԋͳͲͰ͸ɺΘ͟Θ͟ެࣜαΠτͷϓϩάϥ 60
  59. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.4 ஌ݟΛಧ͚Δٕज़ ϜҰཡ͔ΒεϐʔΧʔϓϩϑΟʔϧ΁ͱϦϯΫΛͨͲͬͯ΋Β͏Θ͚ʹ͍͖·ͤΜͷͰɺ ඞͣ๯಄ʹؚΊ͓͖ͯ·͠ΐ͏ɻ

    • લఏ৚݅ – લఏ৚݅ʹ͸ɺ૝ఆ͍ͯ͠Δର৅ಡऀ΍ٕज़ϨϕϧɺഎܠͳͲΛࠩ͠ࠐΜͰ͓͘ͱɺड͚ खͷ࢟੎͕มΘ͖ͬͯ·͢ɻ·ͨɺ࠷ॳʹड़΂͓ͯ͘͜ͱͰɺ࠷ऴతͳظ଴஋ͷζϨΛ๷ ͙͜ͱ͕Ͱ͖·͢ɻ • ۩ମྫ – ຊฤͷதͰ͸஌ࣝΛड़΂Δ͚ͩͰͳ͘ɺݸਓతʹݕূͯ͠Έͨ݁ՌͰ΋Α͍ͷͰɺ۩ମྫ ΛϑΝΫτͱؚͯ͠ΉΑ͏ʹ͠·͠ΐ͏ɻ ετʔϦʔΛඳ͘ খֶߍͷतۀͷΑ͏Ͱ͕͢ɺϒϩάΛॻ࣌͘΋ϓϨθϯςʔγϣϯΛ͢Δ࣌΋ɺىঝస݁͸େࣄͰ ͢ɻ͜͜·Ͱड़΂͖ͯͨΞ΢τϓοτͷཁૉͱͳΔ֤ύʔπΛɺىঝస݁ʹམͱ͠ࠐΈɺ࿩ͷྲྀΕΛ ࡞Δ͜ͱͰɺ཈༲ͷ͋ΔετʔϦʔ͕Ͱ͖͕͋Γ·͢ɻձ࿩΍จষʹϦζϜ͕͋Δͱड͚औΔଆʹ ͱͬͯ͸ɺ࿩ʹೖΓࠐΈ΍͘͢ͳΔ΄͔ɺॏཁͳϙΠϯτͳͲ͕఻ΘΓ΍͘͢ͳΓ·͢ɻ ਤ 6.3: ຊষΛىঝస݁Ͱ੔ཧͨ͠΋ͷ ཧղ͠΍͍͢೔ຊޠΛ࢖͏ ೔ຊޠʹ͸ɺྑ͘΋ѱ͘΋ز௨Γ΋ͷදݱ͕ଘࡏ͠·͢ɻ࢖͍ํΛؒҧ͑Δͱɺͦͷ৘ใͷຊ࣭͕ ݟ͑ʹ͘͘ͳͬͯ͠·ͬͨΓɺޡೝΛҾ͖ىͯ͜͠͠·͏͜ͱ΋͋Γ·͢ɻ೔ຊޠ͸ಥ͖٧ΊΔͱԞ ਂ͘ɺ࣌ʹศརͰ͋Γɺ࣌ʹ೉͍͠ݴޠͰ͕͢ɺݴ༿ͷઐ໳ՈͰ͸ͳ͍ιϑτ΢ΣΞɾΤϯδχΞ͕ ࠷௿ݶ཈͑Δ΂͖ϙΠϯτΛɺҎԼʹ 3 ͓͖ͭ͋͛ͯ·͢ɻ 61
  60. ୈ 6 ষ ஌ݟΛಧ͚Δٕज़ ʙͦͷΞ΢τϓοτɺಧ͍ͯ·͔͢ʁ ʙ 6.5 ·ͱΊ • ਖ਼͍͠೔ຊޠΛ࢖͍ͬͯΔ͔ʁ

    – ޡࣈ୤ࣈɺ ʮͯʹΛ͸ʯͷॿࢺ΍म০ޠͷ࢖͍ํɺओޠɾड़ޠͷؔ܎ͳͲ͕ߟྀ͞Εͨਖ਼ ͍͠೔ຊޠΛ࢖͏͜ͱͰɺ༨ܭͳ͜ͱͰࢥߟ͕अຐ͞ΕΔ͜ͱͳ͘ɺμΠϨΫτʹ૬खʹ ಧ͖ɺ࿩ͷ಺༰͕఻ΘΓ΍͘͢ͳΓ·͢ɻ • γϯϓϧͳ೔ຊޠʹͳ͍ͬͯΔ͔ʁ – ҰจͰଟ͘ͷ͜ͱΛޠΓ͗͢Δͱɺओޠ͕Θ͔Βͳ͘ͳͬͨΓɺճΓ͘Ͳ͍දݱΛ࢖ͬͨ Γ͢Δ͜ͱͰɺҙਤ͠ͳ͍ղऍΛট͘͜ͱʹ΋ͳΓ·͢ɻͳΔ΂͘୹Ίʹγϯϓϧͳදݱ Λ࢖͏Α͏ʹ͠·͠ΐ͏ɻ • ࠷దͳݴ༿Λબ୒͍ͯ͠Δ͔ʁ – ·ͣ͸ઐ໳༻ޠΛਖ਼͘͠දه͢ΔΑ͏ʹ͠·͠ΐ͏ɻࣾ಺༻ޠΛͦͷ··࢖Θͳ͍Α͏ʹ ࣾ֎ͷਓͰ΋Θ͔Δݴ༿ʹஔ͖׵͑ͨΓɺݱ୅ਓ͕Α͘࢖͏ݴ༿ΛબͿ͜ͱͰɺ୭Ͱ΋ཧ ղ͠΍͘͢ͳΓ·͢ɻେֶͷڭՊॻɺಡΈʹ͔ͬͨ͘ܦݧ͸͋Γ·ͤΜ͔ʁ ࣗ෼Ͱ΋೔ ৗతʹ࢖͏ݴ༿ΛબͿΑ͏ʹ͢Δͱɺλʔήοτʹ΋఻ΘΓ΍͍͔͢΋͠Ε·ͤΜɻ ຊষͷ๯಄ʹ΋ॻ͖·͕ͨ͠ɺ͜͜Ͱ͸ʮ஌ݟΛಧ͚ΔΞ΢τϓοτʯʹϑΥʔΧε͠ɺ঎඼΍ αʔϏεΛചΔͨΊͷ޿ใɾϚʔέςΟϯάࢪࡦͱͯ͠ͷΞ΢τϓοτʹؔͯ͠͸ॻ͖·ͤΜͰ͠ ͨɻϚʔέςΟϯά໨తͷ৘ใൃ৴ʹ͸ɺͦͷاۀͰఆΊΒΕͨಠಛͷϑΥʔϚοτ͕͋ͬͨΓɺϒ ϥϯυɾΠϝʔδʹଈͨ͠ݴޠ΍දهํ๏͕ܾΊΒΕ͍ͯͨΓͱɺ७ਮʹ஌ݟΛಧ͚͍ͨ৔߹ʹ͸ඞ ཁͷͳ੍͍໿͕ଘࡏ͠·͢ɻՃ͑ͯɺਖ਼͍͠೔ຊޠΛ࢖͍ɺత֬ʹ৘ใΛಧ͚Δ͜ͱΑΓ΋ɺ঎඼͕ ࢢ৔ʹ޿͘ೝ஌͞ΕɺΑΓଟ͘ͷফඅऀʹڵຯΛ࣋ͬͯ΋Β͏͜ͱ͕ॏཁࢹ͞Ε·͢ɻ஌ݟΛಧ͚Δ ͨΊͷΞ΢τϓοτͱ঎඼ͷັྗΛ޿ΊΔͨΊͷΞ΢τϓοτͱͰ͸ɺ্هͷΑ͏ͳߟྀ͢Δ΂͖ϙ Πϯτ͕ҟͳͬͯ͘ΔͨΊɺຊষͰ͸আ֎͍͖ͤͯͨͩ͞·ͨ͠ɻ 6.5 ·ͱΊ ຊষ͸චऀͷܦݧ͔Β·ͱΊͨ΋ͷʹͳΓɺ͓ͦΒؒ͘ҧ͍΍ҟ࿦΋͋Δͱࢥ͍·͢ɻͦ΋ͦ΋͜ ͷจষʹ΋ࣗ৴͕͋ΔΘ͚Ͱ͸͋Γ·ͤΜ͕ɺຊষ͕ʮ஌ݟΛಧ͚Δٕज़ʯʹ͍ͭͯੈͷதͷٕज़ऀ ͷํʑͷؒͰߟ͑ΒΕΔ͖͔͚ͬͱͳΓɺΑΓଟ͘ͷՁ஋͋ΔΞ΢τϓοτ͕ҲΕͯɺٕज़ྗ΍։ൃ ྗͷ޲্ʹͭͳ͕Ε͹޾͍Ͱ͢ɻ 62
  61. ஶऀ঺հ দݪ ৴஧ (ୈ 1 ষ୲౰, GitHub: matsubara0507) ॴଐ͸ϞϯεταʔόνʔϜͰ Ruby

    ΍ Go Λॻ͍ͯΔɻϓϩάϥϛϯά͕޷͖Ͱɺීஈ͸ਪ ͠ݴޠͷ Haskell Ͱ༡ΜͩΓɺ৽͍͠ϓϩάϥϛϯάݴޠΛษڧͨ͠Γ͍ͯ͠ΔɻHaskell-jp ΍ Elm-jp Ͱͪΐͪ͜ΐ͜׆ಈ΋͍ͯ͠Δɻ ొ಺ խਓ (ୈ 2 ষ୲౰, GitHub: tonouchi510, Twitter: @tono2700) Ո଒ΞϧόϜ ΈͯͶ Ͱ ML ΤϯδχΞΛ΍͍ͬͯ·͢ɻ࠷ۙ͸ CloudTPU Λ࢖ͬͯϦον ʹݚڀ։ൃͯ͠·͢ɻ ௥ా ହ޺ (ୈ 3 ষ୲౰) KARASTA ͷ Android/iOS ΞϓϦΛ࡞Δ࢓ࣄΛ͍ͯ͠·͢ɻKARASTA Ͱ͸ௌ͖ઐͱͯ͠ ೔ʑ׆ಈ͍ͯ͠·͢ɻ ౻ా ग໳ (ୈ 4 ষ୲౰, GitHub: shumoon84, Twitter: @shumon_84) ։ൃຊ෦ө૾ٕज़άϧʔϓͰ TIPSTAR ͷө૾഑৴ج൫ͷόοΫΤϯυΛ࡞͍ͬͯ·͢ɻ10 ݄ʹҟಈ͢Δ·Ͱ͸ Unity Λ͍ͯ͠·͕ͨ͠ɺ࠷ۙ͸ Go ͹͔Γॻ͍͍ͯ·͢ɻ ຊؒ ৺ (ୈ 5 ষ୲౰, GitHub: july1997, Twitter: @AQUA_july) Ϋϥ΢υΛ׆༻ͨ͠ɺAIɾσʔλΤϯδχΞɻϚϧνϓϨΠήʔϜʹ΋ڵຯ͕͋Γ·͢ɻײ ૝ɺͦͷଞ͝࿈བྷ͸ͪ͜Β·Ͱɿ[email protected] ਿా ֆඒ (ୈ 6 ষ୲౰ɾ੍࡞ਐߦ, GitHub: esugita, Twitter: @semiemi7) ࠓ·Ͱ͸ DevRel ͱͯ͠ɺॻ੶ͷ੍࡞ਐߦ΍ࣾ಺ͷॸ຿Λ୲౰͍ͯ͠·͕ͨ͠ɺࠓճɺॳΊͯ ࣥචଆʹ΋ճͬͯΈ·ͨ͠ɻେมͦ͏ͬͯࢥͬͯ·͕ͨ͠ɺຊ౰ʹେมͳΜͰ͢Ͷʢۤসʣ 63
  62. mixi tech note #05 2020 ೥ 12 ݄ 26 ೔ɹॳ൛ୈ

    1 ࡮ɹൃߦ ஶɹऀ גࣜձࣾϛΫγΟ ༗ࢤ ൃߦॴ גࣜձࣾϛΫγΟ ҹ࡮ॴ ೔ޫاը ɹ ˜ mixi, Inc.