2024年5月を振り返る

RubyKaigi に参加

8年ぶりぐらい(京都開催以来)に RubyKaigi に参加しました。

感想ブログはこちら:

dawn.hateblo.jp

まだまだ RubyRails でやっていくぞ!!!という気持ちを新たにした

KaigiEffect

RubyKaigi で刺激を受け、zlib gem を pure Ruby で書き直すというのをやってみてます。 このブログを書いてから全く進んでないです。

dawn.hateblo.jp

mastodon 盆栽業

思うこと:テストは大事

読んだ本など

これかなりすき

seiga.nicovideo.jp

あとはこのへん

イスラエル 人類史上最もやっかいな問題

そこそこ長い本だったけど非常に面白かった

Unity を触った

曲がりなりにもゲーム業界のはじっこで仕事をやってるにも関わらず Unity の一つもさわれないというのは如何なものか?と思い、これをやってました。

learn.unity.com

なお上記を完走してから一切触ってない模様。

感想:

Unity の Visual Scripting はかなりよくできている。 Visual Scripting で AI を組んで自動で戦闘させるゲームとか作りたい。

伊藤潤二展に行った

www.setabun.or.jp

実は伊藤潤二の作品を全く読んだことがないのだけど、結構面白かった。

Bluesky にアカウントを作った

bsky.app

原理:

mastodon.social

つまり、mastodon のアカウントのミラーです。

自転車

例によって多摩川を走った

social.genya0407.link

OSS 活動

作った gem に PR が来たのでマージしました。嬉しい!

github.com

あと ruby/zlib にちょっとした PR を出したところ無事マージしていただけたので良かったです。

github.com

雑感

今月はいろんな活動をしていた。やはり長期休みは神。

6月は耐え忍んでいきたい。

今月のまとめ

social.genya0407.link

Ruby の zlib gem を pure Ruby で書き直す試み

RubyKaigi 2024 に参加しました。

dawn.hateblo.jp

この記事でも参照していますが、"Breaking the Ruby Performance Barrier" という講演が非常にエキサイティングでした。

僕も YJIT の力を感じたくなり、zlib gem を pure Ruby で書き直してみて、C拡張に比べてどのぐらいパフォーマンスが出るか検証する、というのをちょっとづつ進めています。

zlib とは

zlib は、Deflate (ZIP とか gzip とかで使われる圧縮アルゴリズム) を実装するライブラリです。

zlib - Wikipedia

Ruby から zlib を利用する gem として zlib が存在します。

この gem は端から端まで C 拡張で記述されており、 ext/zlib/zlib.c にすべてのコードが記述されています(テストは Ruby で書かれている)。

リライト方針

ゼロから一気に全部書き換えることを目指すと心が折れそうなので、以下のような手順で漸進的にリライトを進めています。

  • gem の中に Ruby のコードを書く場所を作る
  • pure Ruby のメソッドを書き、対応する C拡張のメソッドをコメントアウトする
  • テストが通ることを確認する
  • これを繰り返す

こんな感じになります(この diff では3つのメソッドを置き換えている):

このようにすることで、テストが通ることを都度チェックできるので確実に進められますし、ちょっとづつ進捗を感じることができるので良いです。

クラスをリライトするときはこの手法が使えず、クラスに所属するメソッドをすべて同時に書き換える必要がある気がしてますが、まあどうにかなるでしょう。

進捗

本日時点では、以下の3つのメソッドの置き換えが完了しています。

  • Zlib.adler32
  • Zlib.adler32_combine
  • Zlib.crc32

そのうち Zlib.adler32 については、ベンチマークやプロファイルを取りつつ最適化を行いました(後述)が、結構大変な思いをしました。 そのため、下の2つについてはとりあえず動けば良しということで真面目に最適化してないです。 一通り書き直したらベンチマークを取ろうと思います。

レポジトリはこちらになります:

Comparing ruby:master...genya0407:feature/pure-ruby · ruby/zlib · GitHub

Zlib.adler32 の最適化

前述のように、Zlib.adler32 を実装するときは真面目に最適化を行ったので、そのベンチマーク結果を書いておきます。

なお、adler32 自体の説明については Wikipedia を参照してもらうのが良いと思いますが、要はバイナリ列のチェックサムを計算するメソッドです。

Adler-32 - Wikipedia

ベンチマークは以下のようなコードで行いました。

require 'benchmark'
require 'securerandom'
require_relative 'lib/zlib'

RubyVM::YJIT.enable

long_string = SecureRandom.bytes(10_000)
Benchmark.bmbm do |x|
  x.report('C-ext') do
    i = 0
    while i < 1000
      Zlib.adler32(long_string)
      i += 1
    end
  end

  x.report('pure Ruby') do
    i = 0
    while i < 1000
      Zlib.adler32_pure(long_string)
      i += 1
    end
  end
end

ローカル環境(Apple M1 Pro)でこのスクリプトを動かしてみたところ、結果は以下のようになりました。

Rehearsal ---------------------------------------------
C-ext       0.000811   0.000018   0.000829 (  0.000825)
pure Ruby   0.061622   0.000084   0.061706 (  0.061824)
------------------------------------ total: 0.062535sec

                user     system      total        real
C-ext       0.000618   0.000001   0.000619 (  0.000616)
pure Ruby   0.046205   0.000026   0.046231 (  0.046362)

pure Ruby 実装の方がだいたい 75 倍ぐらい遅いですね。

ちなみに上記は Ruby 3.3.1 を使ったときの結果ですが、Ruby 3.4.0-preview1 を使うと以下のような結果になりました。

Rehearsal ---------------------------------------------
C-ext       0.000767   0.000017   0.000784 (  0.000780)
pure Ruby   0.035132   0.000063   0.035195 (  0.035337)
------------------------------------ total: 0.035979sec

                user     system      total        real
C-ext       0.000645   0.000001   0.000646 (  0.000645)
pure Ruby   0.020487   0.000003   0.020490 (  0.020547)

pure Ruby 実装の方がだいたい 30 倍ぐらい遅いので、3.3.1 → 3.4.0-preview1 で 2 倍ぐらいは速くなってることがわかります。

なお 3.4.0-preview1 でも YJIT を切ると以下のような結果になります。

Rehearsal ---------------------------------------------
C-ext       0.000837   0.000018   0.000855 (  0.000851)
pure Ruby   0.432514   0.000175   0.432689 (  0.433537)
------------------------------------ total: 0.433544sec

                user     system      total        real
C-ext       0.000662   0.000002   0.000664 (  0.000662)
pure Ruby   0.426348   0.000069   0.426417 (  0.426842)

pure Ruby 実装のほうが 645 倍ぐらい遅いので、YJIT によって 20 倍ぐらい速くなることがわかります。

YJIT はすごいし、進歩も目覚ましいですね。。。

pure Ruby 実装の最適化をしたときの感想

Zlib.adler32 の pure Ruby 実装は C 拡張に比べて 30倍 ぐらい遅いと書きましたが、実はこれは結構頑張って最適化をやった結果です。適当に書くともっと遅いです。

たとえば String から byte 列を取り出すのに、当初は String#bytesString#each_byte が使っていましたが、これらはものすごく遅いです(ruby-prof を使ってプロファイルを取った)。 String#unpack も使ってみましたが、これも結構遅かったです。 Shopify/protoboeuf の実装を軽く見てみたところ String#getbyte が使われていたので試してみたら、これが一番速かったです。

次にボトルネックになったのは Integer#+ に時間がかかるというやつです。 初めは、modulo 演算をするタイミングの問題で Bignum になってしまい、多倍長整数の足し算によって遅くなってるのかな?と疑っていましたが、Fixnum は 63bit もあり、unsigned char を足し算しただけではそんなに簡単に Bignum には突入しないので、単純に Fixnum (実態は long) の足し算に時間がかかっているようです。

このボトルネックは今でも解決できてないのですが、おそらく以下の問題があるのではないかと考えています。

  • while ループ のカウンタをインクリメントする回数が多い?
  • Integer は immutable なので inplace な操作に比べて遅い?
    • たかが long とはいえ、都度新しいオブジェクトを生成しているのは遅い気がする
    • そもそも short で足りるところを long 使ってるのでそれも遅そう
    • GitHub - osyoyu/pf2: A sampling-based profiler for Ruby を使えば C の中のプロファイルが取れるんじゃないかと思って使ってみたが、何も情報が取れなかった。速すぎて sampling profiler ではうまくプロファイルできないのかもしれない。

いずれにせよ、Ruby は C に比べて最適化に使える(危険な)手段が少ないナアとは感じました。 Ruby でそんなことすんなという話はあると思います。

まとめ

いわゆる一つの Kaigi Effect として、zlib を pure Ruby で書き直すという試みを進めています。

Zlib.adler32 については最適化を頑張って、C拡張の30倍遅い程度まで高速化できました。

引き続き暇を見つけて書き換えを進めていこうと思います。

コメント・感想などあれば @genya0407@social.genya0407.link までいただけると嬉しいです(ブクマも歓迎)。

RubyKaigi 2024 in 沖縄に参加した

那覇空港にあった看板

沖縄で開催された RubyKaigi 2024 に参加したので感想をつらつらと綴ります。

講演から刺激を受けた

何よりもまず、この講演がとにかくエキサイティングでした。

Breaking the Ruby Performance Barrier - RubyKaigi 2024

一言でいうと「Ruby 3.3 は C拡張より速い!!」というような内容で、具体的には、Protobuf の gem を pure Ruby で書いてみたら、デコードについては Google 謹製の C拡張の gem より速くなったという話がありました。

GitHub - Shopify/protoboeuf: Experimenting with a protobuf implementation

Google 謹製の protobuf gem はインスコが大変な上に品質もそんなに高くない*1ということもあり、Shopify 謹製の pure Ruby 実装が誕生したらものすごく嬉しいです。

また、このことは、 CPU-bound な処理のパフォーマンスを出すために Go や C で書いてる処理を Ruby で書き直せる機運 が生まれたことを示しています。

今回の RubyKaigi では Ractor や Falcon などの並行並列処理に関するトピックも取り扱われましたし、以下の記事のように、Go で書かれた処理を Ruby で書き直していくムーブメントが生まれたりしたらとてもおもしろいですね。

Goで作ったシステムをRubyでリプレイスすることを検討してみた

また、この講演以外にも面白い講演が数多くあり、普段の業務をこなしているだけでは得られないタイプの刺激をたくさん受けることができました。

多くの方にお会いできた

RubyKaigi では多くの方にお会いすることができました。

  • オフ会のようなもの
    • fediverse や twitter で相互フォローだったがお会いしたことがない方々
      • 学生時代に京都関連でお互いに認知していた人や、mastodon を初めたときに知り合った人等
      • アイコンを印刷して名札に貼っておいたのがかなり効果的だったぽい。来年もやる。
    • PR を出した gem の author
    • 謎に自分を認識してくださっていた方々
      • 自分のほうが一方的に知ってると思ってた方に声をかけていただいて超びっくりしたりした
  • 知人達
    • 学生時代の同期
    • Kaigi on Rails でお話した方
    • 転職していった元同僚
  • IntelliJ の RubyMine 開発者の方
    • 自分はRubyMine を愛用しているので大興奮だった
    • RubyMine への愛を伝えたかったが、英語の下手さに起因して、いいかんじにコミュニケーションが取れなかったのは反省(愛は伝わったと思う)
      • 英語の講演を聴くのが厳しかったということもあり、何らかの手段で英語力(特にヒアリング)を高めたいというモチベーションが生まれた
    • developer 向けツールの会社がスポンサーブースを出してくれるとこういうことがあってすごく良いと思いました
  • 生 Matz
    • 握手していただきました!!

みなさんありがとうございました!来年の RubyKaigi でもよろしくお願いします!!

沖縄

とにもかくにも沖縄が最高だった。

Day 4 ぐらいしかガッツリ観光できなかったので心残りが大きい。 RubyKaigi じゃない機会にまた行きたい。

まとめ

social.genya0407.link

*1:品質が高くないというか全体的に RubyRuby 界に詳しくない人が作ってるんじゃないかなという雰囲気を感じる

2024年4月を振り返る

小石川植物園に行った

koishikawa-bg.jp

やや葉桜気味だったけど桜が綺麗で良かったです。

前橋へ一泊二日の旅行

ちょっといい感じのホテルに泊まって、ご飯が美味しかったです。

近くの川(広瀬川)がきれいで人も少なくてよかった。

www.maebashi-cvb.com

これは川沿いにある岡本太郎のオブジェ的なやつ。

臨江閣にも行った。思ったよりずっと良かった。 臨江閣自体も良かったけど、その近くにある公園も良かった。

www.city.maebashi.gunma.jp

ちなみに臨江閣はむかしブラタモリで取り上げられたことがある。

帰りに普通車のグリーン車に乗ったんだけどモバイルSuicaグリーン車乗車体験が非常に良かったのでまたやりたい

唐木田から南多摩まで歩いた

久しぶりにロング・散歩をしたいと思い、唐木田から南多摩まで13kmぐらい歩いた。 最後の方は結構疲れちゃったけど、多摩の春を感じられたので良かった。

ユニコーンオーバーロードをトロコン

social.genya0407.link

だいたい100時間ぐらいプレイした。

すごく面白かったけど、ユニット編成システムとRTSの食い合わせの悪さをどうしても最後まで感じざるを得なかった。

genya0407.hatenadiary.jp

これをさらに発展・洗練させたらとんでもなく面白いものができそうなので、今後の発展に強く期待という感じ。

「Voice of Cards ドラゴンの島」のプレイを開始

www.jp.square-enix.com

ユニコーンオーバーロードをクリアしたので、前からちょっと気になってたゲームを始めてみた。

感想:

  • 絵が綺麗でグラフィックが綺麗で、それだけで気持ちいい
  • 戦闘システムは古典的なRPGぽい
  • シナリオにちょっとひねりが入っていて良くも悪くも特徴的であり、ユニコーンオーバーロードのシナリオとは対照的である
  • テンポちょっと悪いかもと思ったけど設定変えたら快適になった

まあクリアまでは楽しく遊べるかなという感じ。

法学入門を読んだ

genya0407.hatenadiary.jp

mastodon 盆栽業を実施

会社に弁当を持参するようになった

ふるさと納税で米を買いすぎたので少しでも消費したいという思いから、弁当を作って会社に持参するようになった。 人生で初めて弁当を作ったので色々と新鮮です。

最近はちょっと頑張って三色丼を作ったり、ご飯詰めて冷凍食品を入れたりしている。海苔弁が楽で良い。

低負荷で続けられる感じなので、しばらくはやると思う。

今月のまとめ

social.genya0407.link

2024年3月を振り返る

たばこと塩の博物館に行った

ここは本当に面白かったのでオススメです。入館料も異様に安い。

www.tabashio.jp

これは企画展にあった巨大な何かです。

博物館には全く関係ありませんが、周辺を散歩していたら謎のオブジェ?があったのでシェアーします。

Bluetooth イヤホンを新調

STATUS BETWEEN 3ANCmodernity.jp

所感

  • 左右が分離してるタイプの無線イヤホンはマスクと干渉しないので良い
    • これまでは左右が紐でつながっているようなのを使っていたが、マスクとの装着順を考える必要があって面倒だった
  • ノイズキャンセリングがちゃんとしてる
    • 職場でこれつけてると呼びかけられても気付けないぐらいの感じ
  • バッテリーはちょっと弱いかも?
    • 弱いと言っても困ることはない。前の前に使ってたイヤホンが異常に電池の持ちがいいやつだったから、それに比べたら弱いという程度。

Ahamo を離脱して Povo 2.0 に移行

Ahamo の電波悪すぎやろという感想になり、Povo 2.0 に移行した。

移行手続きは想像以上に楽で、回線変更時のダウンタイムもなければ店に行く必要すらなかった。 こんな簡単にできるならもっと早くやればよかった。

Povo の回線がめっちゃいいかというとよくわからんが、、、以前に比べると「ここで繋がらんのかい!!」となることは減ったような気がする。 でも電波は強くても通信が遅いという現象はちょいちょいある。物理レイヤじゃなくてソフトウェアレイヤ(上流)で詰まってる?

読んだ本

この辺の本を読んでました

非常にえきさいちんぐかつ何らかの役に立ちそうというか、労働をするうえで物事の見方が変わるような体験ができたのでよかった。

普通に働いている中での悩み事とかをこの辺の枠組みで考える癖がついてしまったような感じもあり(一応言っておきますがこの本は自己啓発本ではないです)、それだけは良くないと思っている。

カウンセリングを受けた

genya0407.hatenadiary.jp

結論としては非常に面白い体験だった。

自転車

暖かくなってきたので何回か自転車に乗るなどした。 自宅から多摩湖までいい感じのサイクリングロードになっていることを発見したのでちょいちょい行こうと思います。

荒川を走りに行ったりしたんですけど、荒川までの道があんまりいい感じじゃないのでしんどかった。別のルートを開拓したい。

social.genya0407.link

mastodon

  • misskey の quote をいい感じに表示できるようにする
  • 画像を EBS から S3 に移動する
  • federated timeline を充実させるための bot を作る

などの活動をしていました。

だんだん mastodon の中身に詳しくなってきた。 コードリーディングの能力は仕事を始めてから顕著に向上したものの一つだなと思う。

ユニコーンオーバーロードをやっている

genya0407.hatenadiary.jp

仕事

なぜか C++ と向き合う羽目になっている。 数年前にプロジェクトにいた人が書いた「テンプレートを生成するマクロを生成する Ruby スクリプト」と格闘するなどしていた。

質問箱を閉じた

質問がある方は @genya0407@social.genya0407.link にメンションしてください。

しょうもない質問が来なくなってQoLが向上した。もっと早くやればよかった。

質問箱、質問する側は完全に匿名で好きなことを言えるのに、回答する側は言ったことが半実名みたいな感じで全世界に公開されてしまうので、全くフェアな仕組みではない。

むかしはそういう状況で質問よりもヤバい返しをするみたいなプロレスをすることによってある種の承認欲求を満たしていたわけだけど、もうこの歳になるとそれにも飽きて、ただただしょうもない質問に心をささくれ立たせるだけのものに成り果てていた。 ずっと前から惰性で続けていたのだけど、ここ数日本当にしょうもない質問が連続で飛んできて嫌気が頂点に達したので、質問フォームを閉じた。

なにか言いたいことがあるなら、半匿名でもいいから発言者と紐づいた形で文章を送信してほしい。

俺はせいせいした気分だ。お前はどうだ?

5年もの間、気分の悪くなるような質問を送り続けていた、匿名でしか人に物を言えない「お前」からの「質問」を受け取ることはもうないだろうけどな。

今月の所感

ブログ書いてて思ったけど、今月はちょいちょい「もっと早くやればよかった」ということをやれたので良い月だったかもしれない。

social.genya0407.link