- Ruby / Rails関連
週刊Railsウォッチ: Wasm Workers Server 1.0、mruby 3.2.0リリース、irbtoolsほか(20230315後編)
こんにちは、hachi8833です。
🔗Ruby
🔗 Wasm Workers Server 1.0でPythonとRubyをサポート
Wasm Workers Server v1.0.0 is out. We are happy to announce the support for Python 🐍, Ruby 💎 and more languages in the future!
From now on, you can create worker-based serverless apps using any of these languages and run them in #WebAssembly 🚀https://t.co/oeceLzHQTO
— Wasm Labs (@vmwwasm) February 23, 2023
つっつきボイス:「Wasm Workers ServerというWebAssemblyサーバレス基盤でruby.wasmやpython.wasmも動かせるようになったのね: これは面白そう」「これまではRustのWasmしか動かせなかったみたいですね」「Wasm Workers Serverは、よく見るとVMwareが運営してる」「ホントだ」
参考: オープンソースのWebAssemblyサーバレス基盤「Wasm Workers Server 1.0」正式リリース。RubyとPythonのWASMランタイムに対応し、Ruby/Pythonでの記述が可能に - Publickey
参考: VMware Japan:クラウド、モビリティ、ネットワークとセキュリティ | JP
「コマンド名はwws
↓」
# 同記事より: お試しコマンド
curl -fsSL https://workers.wasmlabs.dev/install | bash && \
wws runtimes list
「wws
コマンドでこうやってローカルサーバーを起動できるんですね↓」
# 同記事より
wws
⚙️ Loading routes from: .
🗺 Detected routes:
- http://127.0.0.1:8080/
=> ./index.py (name: default)
- http://127.0.0.1:8080/ruby
=> ./ruby.rb (name: default)
🚀 Start serving requests at http://127.0.0.1:8080
🔗 Ractorビギナーズガイド(Ruby Weeklyより)
# 同記事より
def tarai(x, y, z) =
x <= y ? y : tarai(tarai(x-1, y, z),
tarai(y-1, z, x),
tarai(z-1, x, y))
require 'benchmark'
Benchmark.bm do |x|
# sequential version
x.report('seq'){ 4.times{ tarai(14, 7, 0) } }
# parallel version
x.report('par'){
4.times.map do
Ractor.new { tarai(14, 7, 0) }
end.each(&:take)
}
end
つっつきボイス:「Honeybadgerの記事です」「基礎的な内容に徹して短くまとめられた記事: Ractorを初めてやる人向けのチュートリアルによさそう👍」
参考: ruby/ractor.md at master · ruby/ruby · GitHub
🔗 !value.nil?
はvalue != nil
よりずっと高速(Ruby Weeklyより)
つっつきボイス:「コードとベンチマークのシンプルなGistです」「value != nil
でvalue
の内容がメソッドなら中身も見に行くのでその分遅くなるのかなと思ったけど、Gistのvalue
はシンプルな1
だし、考えてみたら!value.nil?
もその点は同じですね」「それもそうですね」「nil?
メソッドは利用頻度が高い分最適化が進んでいるんだろうか?」
「!value.nil?
の方がRubyらしい書き方ですし、そもそも!= nil
という書き方はあまり癖にしない方がいいでしょうね」「たしかに」「nil == nil
が成立するかどうかは言語によって違う可能性があるかもしれないので(例: SQLではNULL = NULL
がfalseになる)、nil
をチェックする専用の書き方があるならそれを使うことを習慣づけておく方が、言語や処理系が変わった場合にハマりにくいかなと個人的に思います」
「Gistのレスに、これをRuboCopに入れるべきと書かれてますね: 速くてRubyらしく書けるならRuboCopに入れてよさそう👍」
参考: Object#nil?
(Ruby 3.2 リファレンスマニュアル)
後で自分でもbenchmark_driverで動かしてみました。Ruby 3.2.1, 3.1.3, 3.0.5, 2.7.7を使いました。
▶コード(クリックすると開きます)
#!/usr/bin/env ruby
require 'benchmark_driver'
Benchmark.driver do |x|
x.rbenv "3.2.1", "3.1.3", "3.0.5", "2.7.7"
x.prelude %{
def not_eq_nil
n = 1_000_000
value1 = 1
value2 = nil
n.times do
value1 != nil
value2 != nil
end
end
def not_value_nilcheck
n = 1_000_000
value1 = 1
value2 = nil
n.times do
!value1.nil?
!value2.nil?
end
end
}
x.report('not_eq_nil')
x.report('not_value_nilcheck')
x.compare!
end
# 実行結果
$ ruby bench.rb
Warming up --------------------------------------
not_eq_nil 7.443 i/s - 8.000 times in 1.074826s (134.35ms/i)
not_value_nilcheck 46.295 i/s - 50.000 times in 1.080038s (21.60ms/i)
Calculating -------------------------------------
3.2.1 3.1.3 3.0.5 2.7.7
not_eq_nil 7.500 6.702 7.796 8.672 i/s - 22.000 times in 2.933199s 3.282593s 2.822123s 2.536985s
not_value_nilcheck 46.167 29.985 30.882 33.898 i/s - 138.000 times in 2.989180s 4.602239s 4.468657s 4.070990s
Comparison:
not_eq_nil
2.7.7: 8.7 i/s
3.0.5: 7.8 i/s - 1.11x slower
3.2.1: 7.5 i/s - 1.16x slower
3.1.3: 6.7 i/s - 1.29x slower
not_value_nilcheck
3.2.1: 46.2 i/s
2.7.7: 33.9 i/s - 1.36x slower
3.0.5: 30.9 i/s - 1.49x slower
3.1.3: 30.0 i/s - 1.54x slower
🔗 pid_cache: Process.pidの速度低下を改善(Ruby Weeklyより)
つっつきボイス:「Shopifyのgemです」「glibc 2.25からgetpid(2)
のキャッシュがなくなったために、新しいLinux環境だとRubyのProcess.pid
が遅くなるのか」「Ruby側でキャッシュを持たせることで同等のことをRubyのレイヤで行うgemなんですね」
参考: Process.#pid
(Ruby 3.2 リファレンスマニュアル)
参考: GNU Cライブラリ - Wikipedia(glibc)
Process.pid
呼び出しをキャッシュすることで、現代のLinuxでは無駄なものとなったシステムコールの多くを回避する。
RubyのProcess.pid
は標準のlibc
getpid(2)
を呼び出す。libc
のほぼすべての実装は歴史的にシステムコールを毎回呼ぶのを避けるためにこの関数をキャッシュしていた。しかし2017年にリリースされた
glibc
2.25ではこのキャッシュが廃止され、PIDを頻繁に監視するアプリケーションでパフォーマンスのリグレッションが発生した。これが削除された理由は、一部の低レベルライブラリがこのシステムコール自身を呼び出すことでforkし、キャッシュのクリアを担当するコードをバイパスしていたためである。
しかしRubyでこれを行うのは不可能なので、PIDを安全にキャッシュする形でパフォーマンスをある程度改善できる。
このgemはRuby 3.3で提案されている機能(#19443#note-7)のバックポートであり、おそらくRuby 3.3ではこのgemを使えなくなるだろう。
同リポジトリREADMEより
「このgemは、Ruby 3.3で提案されている変更のバックポートなんですね」「byroot (Jean Boussier) さんのベンチマーク結果(#19443#note-3、#19443#note-4)を見て計算してみると、glibcのバージョンによって0.05usくらいの速度で動いていたシステムコール呼び出しが0.28usくらいかかるようになってしまっていて、確かにオーバーヘッドが大きい」「こんなことが起きていたとは」「これは対応する価値があるでしょうね👍」「Ruby 3.3にも入って欲しいですね」
参考: Feature #19443: Cache Process.pid
- Ruby master - Ruby Issue Tracking System -- 現在オープン
🔗 mruby 3.2.0リリース(Ruby Weeklyより)
- 元記事: mruby 3.2.0 released
つっつきボイス:「mrubyも着々とバージョンが上がってますね」「mruby-bigintというgemで多倍長整数を使えるようになったんですって」
後で探すと、mruby-bigintはmrubyのリポジトリの中にありました。
参考: mruby/mrbgems/mruby-bigint at master · mruby/mruby · GitHub
🔗 irbtools: IRBの機能を強化(Ruby Weeklyより)
つっつきボイス:「IRBを拡張するツールだそうです」
「look
でメソッドをancestorごとにグループ化して表示する機能↓、これはすぐにでも欲しい❤️」
# 同リポジトリより
>> look "str"
.
.
.
Comparable
< <= == > >= between? clamp
String
% crypt inspect squeeze!
* dedup intern start_with?
+ delete length strip
+@ delete! lines strip!
-@ delete_prefix ljust sub
<< delete_prefix! lstrip sub!
<=> delete_suffix lstrip! succ
.
.
.
「このツールの機能が本家IRBに取り入れられるかもしれませんね」「IRBもどんどん強くなってるので、この勢いで入るといいですね」
後でIRBメンテナーの1人である@st0012さんに尋ねたところ、irbtoolsは既にIRBメンテナーにも知られているそうです。
また、以下のRailsへのプルリクも興味深いと思うよとst0012さんから教えてもらいました↓。
参考: Make irb a railties dependency by st0012 · Pull Request #47442 · rails/rails -- マージ済み
上のプルリクメッセージで、Ruby 3.3でbundled gemsやdefault gemsの編成変更が進められていることを知りました↓
参考: Feature #19351: Promote bundled gems at Ruby 3.3 - Ruby master - Ruby Issue Tracking System
🔗 その他Ruby
第17章まで本文すべてをフィードバックできるようになりました!! 万葉衆の有志に全文読破されてしまったので新規コンテンツ「日本の読者の皆さんへ」をJeremyから取り寄せて訳出しましたッ!! Rubyと共にあらんことを -『研鑽Rubyプログラミング』β版が更新されました(β3) https://t.co/D9BCNFfgIE pic.twitter.com/kXLjLkN3Hh
— Kakutani Shintaro (@kakutani) February 16, 2023
つっつきボイス:「気づくのが遅れましたが、『研鑽Rubyプログラミング』の翻訳がひととおり終わって、全ページの翻訳+Jeremy Evansさんの日本語版向けあとがきをβ3版で読めるようになったそうです」「お、正式版のリリースが近づいていそうですね👍」「既にβ版を購入した人は無料で読めるそうです」
- 元記事: Ruby のリリース一覧
「こちらはruby-jp Slackで知りました: これまで英語版にしかなかった過去のRubyリリースの詳しい一覧が日本語版にも全部反映されたそうです」「Ruby 1.6.7から3.2.0までのリストって壮大」「自分が触り始めたのは1.8とか1.9あたりだったかな」
参考: Ruby Releases(英語版)
🔗CSS/HTML/フロントエンド/テスト/デザイン
🔗 スライド『全ブラウザ対応したcontainer queryは何がスゴイのか?』
つっつきボイス:「少し前に公開された、マネーフォワードの鹿野壮さんによるスライドです」「最近話題のコンテナクエリのわかりやすい解説👍」
「従来のメディアクエリではビューポートを基準にするので、ネストしたコンテナのレスポンシブ対応やブレークポイントの変更などがつらかったけど、コンテナクエリは任意の要素を基準にするので明らかに書きやすいですね」
メディアクエリーの使用 - CSS: カスケーディングスタイルシート | MDN
「これもそのとおりだと思います↓: コンテナクエリはコンポーネントのためにあるといっても過言ではないでしょうね」
後編は以上です。
バックナンバー(2023年度第1四半期)
週刊Railsウォッチ: Devise 4.9のHotwire/Turbo統合に対応する、英国政府のViewComponentほか(20230314前編)
- 20230308後編 Ruby30周年記念イベント、37signalsのデプロイツールmrskほか
- 20230307前編 Action Mailerプレビューで全メールヘッダーを表示可能に、rubocop-graphqlほか
- 20230222後編 Ruby 3.2のData#initializeの設計、ruby-openai gemほか
- 20230221前編 Ruby30周年記念イベント、ActiveRecord APIクイズほか
- 20230215後編 Bundler 2.4リリース、RubyKaigi 2023参加募集開始ほか
- 20230214前編 AssumeSSLミドルウェア追加、Fly.ioとRails 7.1のDocker対応ほか
- 20230202後編 ShopifyのYJIT記事、RubyGemsのgem execコマンドほか
- 20230201後編 Ruby 3.2のベンチマーク記事、dry-cliで高度なCLIを作るほか
- 20230131前編 Evil Martiansが使っているgem、JavaScriptガイドが更新ほか
- 20230125前編 2022年のRails振り返り記事、RailsにDocker関連ファイルが追加ほか
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)