ENECHANGE Developer Blog

ENECHANGE開発者ブログ

RubyKaigi 2019 基調講演 The Year of Concurrency by Matz

ENECHANGE で働いている id:cuzic です。

RubyKaigi に来ています。 RubyKaigi は楽しいですねっ! 最新の Ruby の開発状況を知ることができます。

今回の記事では Matz さんの講演内容を書き下していたので、 それを少し整形して、公開します。

変なところとかあれば、コメント欄でご指摘ください。

前座

  • けっこう、初参加の方がいた
  • アメリカ、カナダ、台湾、ロシア、ウルグアイなどいろんな国から来てた方がいた

スポンサーセッション GMO ペパポ

  • 2003年に福岡で創業。ロリポップが創業事業
  • アウトプットすることが、3つの大切にしていることの1つ
  • さまざまなコミュニティのスポンサーもしている
  • 個人としてペパポとして九州を盛り上げていきたい
  • 福岡の中から付加価値の高い取り組みをしたい
  • fukuoka growth next
    • インキュベーション施設もある。
    • GMOペパポも一緒にやっている
  • 福岡は起業家を増やそうとしている   - DAIMYO Engineer College というのを立ち上げようとしている。
  • 鹿児島オフィスを2月に新設
  • モダンな開発ができる会社、自社サービス運用の会社が地方に少ない
  • モダンな開発ができる会社を地方に作りたかった
  • エンジニアコミュニティの活動をふやしていきたい
  • この3日間が九州のコミュニティのいいきっかけ刺激になれば、と思っている

スポンサーセッョン Raksul

  • 事業も組織も成長している。30種類の印刷商材を扱っている
  • 印刷事業
    • オペレータが目視確認しながら、数時間かけてチェックしていたプロセスを
    • PDF を10数秒で確認できるようにする仕組みに変えたりしている
  • 物流事業
    • 荷主が電話で車を探していたのをドライバーに push 通知して、10数秒でマッチングできるようにしている
    • 社会インフラの解決をしている
  • 広告事業
    • 駅に広告を掲載したり、RubyKaigiスポンサーとして、駅の広告をハイジャックする取り組みもしている
  • 最初は印刷のベンチャーはピンとこなかったが、ブルーオーシャンだと感じた
    • 社会インフラ・仕組みを Ruby を使って解決していきたい。

基調講演 The year of Ruby Concurrency Matz

  • 福岡県
    • Ruby への取り組みを積極的にしてくれている
    • 2ヵ月に一度訪れている
  • 今日は Ruby 3 の話をしたい
    • Ruby は Good と言われている。たぶん。(会場笑い)
    • Ruby は生産的であり、柔軟であり、使っていて楽しい
    • 愛してくれている人がたくさんいる。会場にたくさん来てくれている。
  • Ruby がよくない点もある
    • Ruby は遅い。
      • マルチコアを活用できていない。
    • プロジェクトが大きくなるとRuby の欠点が見えてくる
  • だいたいのことには十分に良い
    • たとえば、GItHub とか、Airbnb とか InstaCart とか、たくさんの会社が Ruby を使ってくれている
    • Ruby は十分に速いということもできる
  • なにかの場合で、限界に達したとしてもそれはそれで問題はない
  • Twitter は最初 2007年 Ruby on Rails で作られていた。
    • Ruby on Rails が前提としている CRUD データベース上で Twitter アプリケーションを作るのは向いていない
    • Scala で再構築された。
    • Twitter は Ruby 1.8 を使い続けていた。
    • 彼らは Ruby 1.9 に移行するべきだった(かも)
  • 1.9 に比較してとても速くなった。
    • Ruby はバージョンがあがるごとに数%ずつ改善している
  • これより多くの改善を Ruby 3 で行おうと思っている

    • Ruby 3 では大きな3つの柱を考えている
    • 静的解析、パフォーマンス、 Concurrency
  • 静的解析

    • 最近は静的解析がとてもホット
    • プロジェクトが大きくなるにつれて、テストがとても苦痛になる
      • テストのサイズが大きくなる
      • 実行時間が長くなる
      • 苦痛になる
    • 告白
      • 私はテストが嫌い
      • テストは DRY じゃない
      • 私たちはプログラムを書きたいのであって、テストを書きたいわけではない
      • 仕方がないので人類はテストを書いている
      • もっと生産的になりたい
    • ほかの言語では、静的型のアプローチを使っているのが多い
      • PHP では Type Hinting を導入
      • Python でもアノテーションを導入
      • JS でも TypeScript がある
    • 静的型チェックを導入するのがトレンド
    • 我々はどうするか?
      • Type Annotation を入れようかという話になった
      • 正直やりたくない
      • 告白: 私は型宣言がきらい
      • 型宣言を書きたくない。なぜなら DRY ではないから。
      • コンピュータに仕事をさせられているかんじがする
      • テストは仕方なしで書いている
    • 型宣言でも妥協しない
      • 型宣言なしでもできるこがある
    • Ruby 3 についてはいくつかセッションがある。
      • Stripe による sorbet という Type Checker。
      • まつもとそうたろうさんによる Steep
      • Ruby でも型チェックをやろうとしている。
    • 型定義シンタックス
      • 引数、戻り値、クラスモジュール、ジェネリック、インタフェースの型
      • Ruby にちょっと似ているがRuby ではないという文法
      • このパーサも用意する
      • すでに実装がある https://github.com/soutaro/ruby-signature
    • Gems で型定義ファイルを配布するようにすれば、既存のは型情報があるという状態になる
  • Type Profiler
    • 抽象解釈というテクニック
      • 例)呼び出し時の引数が整数だから、引数 a は整数。整数だから足し算できる。
      • 定義済の型情報との矛盾を検出できる
      • rbi ファイルを出力できる
      • その rbi で次の段階の型チェックもできる
    • 万能ではない
      • テストを書いて、それをもとに rbi を作る
      • 必要なら、自動生成されたものをより正確になるように手動で書き換える
    • 型情報を使って静的型チェッカーを走らせることができる
      • Stripe の Sorbet と soutarou さんの steep がある
      • .rbi ファイルのフォーマットがきまったばかりだが、インプットしてとるようにできる
      • Sorbet
        • C++
        • 非常に高速
        • 型チェックは nominal に実行される。
      • プログラムに DSL として型情報を追加できる。
      • より正確で inline な型を書ける
    • Steep
      • より柔軟な型チェックを書くことができる
      • Structurered Typing を実装
      • ふつうのプログラムで型宣言を書かなくても、型チェックができる
      • より正確なものに書き換え、より良い型チェックができる
      • 型宣言を書かなくてもいい
    • 未来の開発環境で、補完とかデバッグに使うこともできる
    • 今回、3つの発表があることで分かるように非常に活発
    • その結果、Ruby3.0 に組み込まれる
    • 非常に期待が持てる
  • パフォーマンス
    • どんな言語でも速すぎるということはない
    • Ruby は伝統的に文句をつけられ続けている
    • もっとたくさんのトラフィックを試すため、とか
    • もっと改善が必要
    • 中国に行って RubyConf China で中国の人と話す機会があった
      • パフォーマンス改善がとてもホットだった。
      • メモリのボトルネックの改善へのニーズが強かった
      • アリババではメモリが問題となっている
      • Ruby では世代別GC、Incrmental GC、Object Compaction などが導入され、
      • フラグメンシーションの解消により Cache miss を減らすことができる
    • メモリは唯一のボトルネックではない
    • ほかに CPU 、IO のボトルネックがある
    • MJIT
      • Ruby のバイトコードを C に変換。GCC でコンパイル、ダイナミックロード
      • 移植性が非常に高い。GCC がサポートしている範囲内でサポートできる
        • GCC は30年以上の歴史を持つ
        • GCC の最適化を活用できる
      • 欠点
        • とても重たい。
        • メモリについて、非常に不利。
        • 最初から分かっている欠点なので、手は加えている。
      • CPU がボトルネックになっているファミコンエミュレータでのベンチマーク
        • 2.8倍速くなっている
      • 一方、Rails アプリケーションでは遅くなる
      • PHP の JIT 導入の事例
        • すごく速くなると聞いた
        • が、WEB アプリケーションを動かすと遅くなる。
      • WEB アプリケーション ではとても多くのメソッドがある
        • メモリのボトルックもある
        • そもそもGCC を起動するから遅い。
      • MIR という軽量JIT を作成。
        • refine して、将来の Ruby に入るかも。
        • VM -> MIR -> MJIT という構図ができるかもしれない
      • ほかのパフォーマンスを改善する方法はマルチコア
      • 静的型の話、JIT の話。いろいろしてきた。
    • マルチコアを使う話はあまり進んでなかった。あまり発表がなかった。
      • 今回のキーノートのタイトルは、今年はコンカレンシーの年にしよう、というのでつけた。
      • unicorn はマルチプロセス。puma はマルチスレッド。falcon はマルチファイバー
    • コンカレンシーモデルをどうするかというのはプログラミング言語の未来にすごく影響する
    • ボトルネックの改善の点でそれぞれ課題がある
    • Fiber
      • 明示的にスイッチ先の指定が必要
      • ボルトネックの解消には役立たない
    • Thread
      • GIL がある。
      • 同時には1つだけが動く。
    • 現在のコンカレンシーモデルである Thread や Fiber で CPU や IO のボトルネックを解消したい
    • マルチコアを使い、安全なモデルを導入したい
    • shared nothing
      • 共有した状態というのは、諸悪の根源
      • erlang とかのほかの言語は immutable なので、できる
      • Ruby では既存の仕様を immutable に変更することはできない。
    • Guild
      • オブジェクトスペースの分離
      • ほかの Guild のオブジェクトスペースには参照できない
      • Deeply Frozen Object というアイデアで効率化する
      • 分離されたオブジェクト空間
        • 外を参照できない
        • immutable なオフジェクトしか受け渡しができない
        • 数字、FrozenString か Symbol か Deeply Frozen Object しか送れない
        • Frozen オブジェクトは書き換えることができない
        • 再帰的にオブジェクトが Frozen なら、それが分かるようにフラグをつける
      • その場合、ほかの Guild に渡しても何も壊さない
        • Actor とか WebWorker(JS)のように使うことができる
        • この文字列を実行してね、と渡す
    • Ruby では Isolated Blockというのを使う
      • 外のグローバル変数とかを参照できなくする
      • これを実装すると、マルチコアが使える
      • CPU負荷の高い処理に使える
    • 未来において、NxM コンカレンシーも使ってよりライトウェイトにできる(かも)
    • Guild というのは、いままでの concurrency モデルとは異なる
      • 使いづらい
      • IOボトルネックの解消には向かない。使いづらい。
    • Nodejs について調査
      • 使っている V8 の VM がすごく速い
      • ノンブロッキングIO が基本である
    • @normalperson が考えた AutoFiber
      • IO 操作でコンテキストスイッチする
      • 勝手に切り替わることがない
      • スレッドよりも簡単に使える
    • IOインテンシブタスクを常に避けることができる
      • 現在の Ruby のスレッドを段階的に移行できる
    • スレッドによるコンカレンシーはとても難しい
    • スレッドを入れたのを後悔している
      • マルチコアの時代を予想できていなかった
    • あまり深く考えずに、Green Thread を Ruby 1.4 とか入れてみた
    • 正しく、効果的に使い、バグを出さなくするのは難しい。
    • Guilds (Isolates)
      • AutoFiber は Fiber ではない
      • 名前が決まっていない
      • Go とか Elixir とかはコンカレンシーの仕組みを言語レベルで持っている
      • Go: goroutine 、Elixir も同じ。
      • 今までのを使えなくするわけにもいかない
      • 使い分けるしかないと思っている
      • 適切な名前が必要。
      • 昨日の開発者ミーティングでは、 Thread を AutoFiber で置き換える意見もある。
      • たくさんのアイデアがあれば、一個ぐらいヒカルものがあるかもしれない。
      • Guild に対するメンバーシップという考え方がだいぶ弱くなってきた。
      • それでは Guild ではない。
      • Guild という名前にゲーム業界からクレームがきた
      • Guild というクラスを使っている
    • やるやる、と言ってやらないこともいっぱいある
      • Frozen String Literals はマジックコメントでなるやつだけど、Ruby 3 ではそうならない
      • 互換性を維持することがとても大変
      • こいつをデフォルトにするのはあきらめた
      • Ruby 3.5 くらいで復活するかもしれないが、3.0 では導入されない
      • ?a リテラルというがあるが、失敗だった。なくすつもりだが、 3 ではなくならない
      • `` をなくすことも画策していたが、3.0 ではなくならない。
    • すごい保守的
      • キーワード引数は変える予定
      • ある部分では confuse なので後悔している
      • 静的型の相性が悪い。そのため、非互換がいくつかある
      • Ruby 3.0 で大きな非互換としては唯一のもの
    • numbered block parameter 。@1 で宣言なしで、1番目のブロック引数にアクセスできる
      • すでに trunk では導入されている。
      • 開発者会議でとても紛糾した。
      • 醜い、とか。@1 はインスタンス変数でないとおかしい、とか。
      • パターンマッチング。正規表現ではない。
    • 関数型言語にあるようなパターンマッチング
      • case、in を使うのは醜い感じもするが、導入される。
      • パターンマッチングの PR が昨日 trunk にマージされた。
      • 最終的にこの文法になるかはわからない。
      • 不具合報告を歓迎している
    • われわれは生き残らないといけない。
      • 私たちは Ruby が好きだから愛すべきプログラミング言語が時代遅れになってほしい
      • みなさんはいい。Ruby がなくなっても、Python とか JavaScript とかいったらいい
      • 私たちは職業
      • Ruby なくなったらほんとうに困る
      • みなさんにとってもなくなったら困ると思っている
      • 新しい Ruby を使ったらもっと良かったというのを提供していきたい、と思っている
      • そのためにも前進し続けたい
      • より良い言語、より生産的な言語
      • あなたにとってメリットになるような言語にしていきたい
    • それって1人ではできない
      • 私自身もたくさん後悔していることがある
      • キーワード引数の仕様に後悔している
      • 今の Ruby は間違えるとなおせない
      • 最初から間違えをおかさないようにする
      • 素早さは失われるが着実に進める必要がある
      • 私のアイデアだけではなく、みなさんの意見をないがしろにしない、というのが大切だと思っている
      • こういうところがダメだと思う、みたいなのを積極的に言ってもらえるととても助かる
      • ただし、投票はうけつけない
    • どうして Rubyを変えるかというと、みなさんをハッピーにしたい。私たちをハッピーにしたい。
      • そうして、世界をより良い場所に変えたいと思っている
      • 作り続けて改善したいと思っている最大の理由
      • コンカレンシーがんばって、来年の12月に出るのを心から期待している
    • いろんな人の働きによって、Ruby の世界はとてもよくなってきた。
      • クックパッドのフルコミッターの笹田さん、遠藤さん
      • マネーフォワードの卜部さん
      • speeeのむらけんさん
      • heroku の中田さん
    • フルタイムでなくても開発してくれている方はたくさんいる。
    • C を書ける方を募集していますし、そうでない方も意見を Redmine で述べていただけたら、と思います
    • 以上