RubyKaigi 2026でPure Ruby Apache Arrow reader/writerという話をする須藤です。RubyKaigi 2026での私の話をより理解できるようになるために簡単に内容を紹介します。
なお、クリアコードはシルバースポンサーとしてRubyKaigi 2026を応援しています。
また、アンドパッドさんが開催するコード懇親会のお手伝いもします。
関連リンク:
背景
私はRubyが好きなのでデータ処理をするときもできるだけRubyを使いたいです。そのためにはRuby用のデータ処理ツールが必要です。ということで、Ruby用のデータ処理ツールを整備するプロジェクトRed Data Toolsを始めました。2016年ころの話です。
Red Data Toolsはいろいろ便利なデータ処理ツールを提供してきました。よくあるデータセットを共通のAPIでダウンロードできるRed Datasets、可視化ツールCharty、データ処理プラットフォームApache ArrowのRubyバインディングRed Arrowたち、Red ArrowベースのデータフレームRedAmberなどです。
ここにRubyだけで実装されたApache Arrow読み書きライブラリーが増えました。それが今回の話になります。
モチベーション
Apache Arrowのかなり初期の頃からRubyでApache Arrowを使える状態にしてきました。Apache Arrowのコミッターになって公式のRubyバインディングを開発したのです。
Apache Arrowは特定のプログラミング言語に依存せずに効率よくデータ交換できるデータフォーマットです。私がApache Arrowに関わりだした頃は、データ処理システム内の各種データ処理モジュールがApache Arrowを介して協調する未来を目指していました。そのシステムでは各種データ処理モジュールは様々なプログラミング言語で実装されています。それでもApache Arrowを使うことでそれらのモジュールは効率よく協調できるのです。RubyからもApache Arrowを使うことができれば、データ処理モジュールを実装するプログラミング言語の1つとしてRubyも有力な候補になるはずでした。
実際に、各種データ処理モジュールがApache Arrowを介して協調する未来は来ました。しかし、Rubyは依然としてほとんど使われていません。少なくとも私はあまり目にしません。(使っているところを見かけたら私に教えて!)
いくつか原因はあるでしょうが、バインディングのインストールまわりが原因の1つではないかという仮説がありました。Rubyだけで実装されたライブラリーと比べると、インストールが失敗しやすい・インストールサイズが大きいなどで問題が発生しやすいです。
ということで、2025年度Rubyアソシエーション開発助成金プロジェクトの1つとしてRubyだけで実装したApache Arrowの読み書きライブラリーを開発しました。
参考:2025年度Rubyアソシエーション開発助成金成果報告
これでもっと気軽にApache Arrowに対応したアプリケーション・ライブラリーを開発する人たちが増えるはず!
内容
Apache Arrow読み書きライブラリーを実装したという話なら、Apache Arrowのフォーマットはこうなっていて、それぞれこんな感じで対応して、ここらへんがマジ難しかったっす、みたいな話になると思うじゃないですか!でも、そんな話はしません。
Apache Arrowのフォーマット自体にある程度詳しいとか興味があるとかいう人がほとんどならそういう話でもよいと思うのですが、RubyKaigi 2026に来る人たちはそうでもないと思うのです。
そのため、そういう話ではなく、Apache Arrowのフォーマットの読み書きを例にして、Rubyで効率よくバイナリーデータを読み書きするにはどうしたらよいかという話をします。そっちの方が役に立つと思うんですよねぇ。まぁ、Rubyでバイナリーデータを読み書きしようとする人もそんなにいるとは思いませんが。。。
ゼロコピー
効率よく(バイナリー)データを読み書きするためのポイントの一つがゼロコピーです。コピー先の領域の確保や、そこにデータをコピーするとか、読み書き対象のデータを変換するとか、そういう処理が重めの処理になります。そのため、それらをしないようにする(= ゼロコピー)と効率よくなります。
多くの場合、Rubyでは数値はゼロコピーできません。Ruby内部の数値表現と同じフォーマットを使っているフォーマットはほぼないからです。表現が違うと変換しないといけないのでゼロコピーではなくなってしまいます。
一方、文字列データはゼロコピーできることがあります。Stringでも条件があえばゼロコピーできますし、IO::Bufferを使えばその条件がもっと緩くなります。
ただ、IO::Buffer#get_stringで部分文字列を取り出すときはコピーしちゃうんですよねぇ。IO::Bufferが持っているデータがfrozenのときはコピーしなくてもいい気がするので、RubyKaigi 2026でだれかそれっぽい人たちに相談しようと思っています。
不要な一時オブジェクトの削減
IO::Bufferは読み込み時は結構便利なので、書き込み時も便利になるといいなぁと思っています。(ただ、便利になる対象としてIO::Bufferが適切なのかどうかはまだなんとも言えないです。)
IO::Bufferは固定長のバッファーなので、自動伸長する書き込み先には不便です。あらかじめ出力サイズを計算しておかないといけないからです。でも、出力サイズの計算と出力処理を分けるのは実装が面倒です。同じような処理を2回しないといけないからです。
IO::BufferがStringのように自動伸長するようになると便利そうな気もするんですが、コンセプト的に大丈夫?という気もします。
IO::Bufferを使わずにバイナリデータを書き込む場合、output.append_as_bytes([integer].pack("L<"))のようなことをしなければいけません。でも、効率のことを考えるとここで不要な一時オブジェクトは作りたくないです。ここの不要な一時オブジェクトというのは、integerを入れる[]と、packの結果のStringです。"L<"は同じStringを使いまわせますし、リテラルの文字列は一度しか作られないような最適化をすることで解消できるので、ここでは気にしなくてもよいです。IO::Bufferの場合はset_valueを使うことで一時オブジェクトを作らずに済みます。
でも、直接ソケットに出力したいときもあるしなー、IO::Bufferじゃない感じでできるといいのかもなーとかモニョモニョしています。これもRubyKaigi 2026でだれかそれっぽい人たちに相談しようと思っています。
今後の野望
Ruby実装のままさらなる高速化をするためにはRuby本体を改良しないといけません。前述のゼロコピーと一時オブジェクトの削減をできるようにするとかです。
他には、高速なビット操作もあると高速化できそうです。Apache ArrowではNULLを表現するためにビットマップを使っているのです。たとえば、popcountという有名なビット操作がFeature #20163で提案されていますが、そういうやつが増えると高速化できそうです。
大きなやつだと、MemoryViewと組み合わせてSIMD対応のJITをできないかなぁと思っています。RubyのArrayは任意のオブジェクトを入れられますが、SIMDをするには同じ型のデータを連続に配置しないといけません。MemoryViewを使うことでそのようなデータを表現できます。RubyのMemoryViewでsumを高速化で示したように、MemoryViewを使うことでSIMDを使って高速にデータ処理できます。ここでは拡張ライブラリーを使いましたが、JITで同じようなことができればRubyで高速なデータ処理実装を書けるようになります。
興味がある人は来年度のRubyアソシエーションさんの開発助成金に応募するのはどうですか?Red Data Toolsのチャットに来てくれればサポートします。なお、私の開発助成金プロジェクトのやりとりは公開しているので、開発助成金がどんな感じで進むのか知りたい人は参考にしてみてください。
期待
私の話を聞いて、一緒に開発したいという人が出てくるといいなぁと思っています。
私の話は3日目のお昼休み前なのですが、3日目のお昼休みとおやつ休みは本屋さんでコーナーゲストというやつをやる予定です。本屋さんに並んでいる本をネタにしたりあるいはしなかったりしながらお話するやつです。私の話に興味を持ってくれた人は、3日目の休み時間に本屋さんに来てくれればお話できます!
また、本屋さんには並んでいない私物の(背表紙が日焼けした)「Rubyのしくみ」と「Effective Ruby」を持ち込んで、おやつ休みの最後くらいに希望者にプレゼントします。欲しい人は来てねー!
お知らせ:クリアコード設立20周年
今年の7月25日にクリアコード設立20周年を迎えます!
7月29日にさくらインターネットさんにイベントスペースを貸してもらってお祝いイベントを開催する予定です。申し込めるようになったらまた告知するので予定を開けておいてください!
また、以下でお祝いメッセージを受け付けています!
- GitHub: https://github.com/clear-code/anniversaries/issues/1
- GitLab: https://gitlab.com/clear-code/anniversaries/-/work_items/1
- Webフォーム: お問合せフォーム (「種類」は「その他」でOK)
- メール:
info@clear-code.com - X: @_clear_code
クリアコードファン(自認)のみなさんはぜひお祝いメッセージを送ってください!私が喜びます!
お知らせ:お仕事をとれる開発者を募集
お仕事をとれる開発者の募集をがんばることにしました。こんな人がクリアコードに入って欲しい!という人をどう説明するとみんなにうまく伝わるのかわかっていないのですが。。。たとえば、開発成果をオープンにした方がお客さんにとってもメリットありますよという提案をするとか、お客さんのこともクリアコードのことも考えた提案をできる人にクリアコードに入って欲しいです。(クリアコードは成果を自由なソフトウェアにしたいです。)
Rabbit
RabbitでGTK 4を使えるようにしたのですが、まだフル機能は使えません。発表する機会があるごとに少しずつ実装を進めていて、今回もいくつか実装を進めました。ただ、まだ、フルスクリーン時に特定のレンダリング結果がおかしくなる問題を直しきれていません。手元で再現できていて、ここらへんがおかしいのだろうなぁというのもわかっているのですが、うまい解決策を見つけられていません。今日・明日で直せるといいんだけど。。。
まとめ
RubyKaigi 2026でApache ArrowのRuby実装の話をします。Red Data Toolsの仲間が増えるといいな。興味を持ってくれた人たちは3日目の休み時間に本屋さんに来てください。
クリアコードはRubyKaigi 2026をスポンサーとして応援します。
クリアコードは20周年を迎えます。お祝いメッセージを待っています。