Ruby の FFI によるメソッド呼び出しのオーバーヘッド

FFI を利用して C のライブラリを呼び出す時のオーバーヘッドがどれくらいなのかと思い調べてみました。

使用したコード

呼び出し時のオーバーヘッドを知りたかったので、処理負荷がかからない単純に加算するだけのコードとしました。

int add(int x, int y)
{
    return x + y;
}

使用したコード一式は https://github.com/Watson1978/ffi-benchmark にあるので、興味がある方はそちらを参照ください。macOS 上でしか試してないので、他の環境だと動かないかもしれません。あしからず。

環境

  • macOS 13.1
  • Apple M1 Max
  • Apple clang version 14.0.0 (clang-1400.0.29.202)
  • ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]

ベンチマーク結果

Warming up --------------------------------------
                 FFI   858.752k i/100ms
              Native     1.637M i/100ms
Calculating -------------------------------------
                 FFI      8.639M (± 0.3%) i/s -     43.796M in   5.069555s
              Native     16.306M (± 0.2%) i/s -     81.842M in   5.019252s

C 言語で直接 bridge を書くことができれば半分くらいのオーバーヘッドで処理を回せそう。

Ruby を Windows 環境でビルド

以前 Ruby の Windows 環境 (備忘録) - @watson1978 の日記RubyWindows でビルドできるように環境を用意したのですが Visual Studio のアップデートなどで手順に差分が生じたので、また備忘録がてら作業ログを残しておきます。

以下の記事を参考にしています。

Visual Studio

https://visualstudio.microsoft.com/ja/ から Visual Studio Community 2022 をダウンロード。

個別のコンポーネントで以下のものをインストール。(これが最小限のコンポーネントなのかは不明)

言語パックのタブで英語環境を入れておく

  • 英語

vcpkg でライブラリをインストール

vcpkg --triplet  x64-windows install libffi libiconv libxml2 libxslt libyaml openssl-windows readline

openssl の代わりに openssl-windows をインストールした。openssl を指定すると v3.0.5 がインストールされる。openssl-windows だと v1.1.1h と古い openssl がインストールされる。古い Ruby は openssl v3.0.5 だとビルドできなかったりするので、openssl-windows を利用した。

bison のインストール

RubyInstaller の pacman を利用した。

pacman -S bison

環境変数の設定

参考にした記事に沿って環境変数を設定したくらい。

Ruby をビルド

Visual Studio をインストールしたときに x64 Native Tools Command Prompt for VS 2022 というコマンドプロンプトがメニューに作成されているので、それを起動するとコンパイラの設定などがいい感じに行われている。

Rubyソースコードを展開したルートディレクトリで以下のコマンドを実行する。

win32\configure.bat --with-opt-dir=/vcpkg/installed/x64-windows
nmake install

フィヨルドブートキャンプのアドバイザーになりました

Kaigi on Rails を聞きながらオンラインブースの reBako.io(リバコ) - イベント開催をオンラインで簡単に。 で雑談していたら、フィヨルドブートキャンプを運営している町田さんにアドバイザーとして招待していただきました。

bootcamp.fjord.jp

gruff のメンテナーになりました

RMagick が ImageMagick 7 に対応できたので、今度は RMagick を使用しているライブラリを見ていこうかとおもい、gruff のオーナーに連絡したら Contributor として招待していただきました。

とりあえず Rubocop を導入したので調教したりしながら、気長にやっていこうと思います。

ImageMagick 7 に対応した RMagick 4.1.0 への移行方法

年始に転職して、現在は Repro株式会社 に所属しています。

昨日 ImageMagick 6 & 7 に対応した RMagick 4.1.0 をリリースしましたので、簡単に移行手順を書きます。

はじめに

ImageMagick 6 と ImageMagick 7 が提供する異なる API インタフェースの差分を吸収するために、作業に取りかかった初期の頃から RMagick のインタフェースを変えないと対応が困難だと判明しておりました。

そのため、RMagick 3.2.0 から RMagick 4.0.0 へバージョンを上げた際に事前にインタフェースのみ変え、RMagick 4.1.0 は内部的な変更のみで ImageMagick 6 と 7 に対応したため、このようなバージョニングになっております。

RMagick 4.1.0 へ移行する

ver 4.0.0 未満をアプリで使用されている場合には、まず RMagick 3.2.0 へバージョンを上げてテストを実行してみてください。

warning: Image#combine is deprecated; use ImageList#combine.

ver 4.0.0 で廃止されるメソッドを使われている場合には上記のような warning メッセージが表示されるので、メッセージに沿って修正が必要となります。

warning メッセージが表示されない場合は、そのまま ver 4.0.0 と ver 4.1.0 へスムーズにバージョンをあげることができるはずです。テストはそれぞれの段階で十分に実施してください。

ImageMagick 7 へ移行する

ImageMagick 7 へ移行しても同様の画像が出力されるようにいくつかバグを直してもらっていたり、メモリ使用量を改善するためのAPI を追加してもらっていたりするため、ImageMagick 7 の最新版を使用されることを推奨します。 (#1160, #905, #894, #891, #817

また、ImageMagick 7 では High dynamic-range imaging (HDRI) というものがデフォルトで有効になっています。詳細はよくわかっていないのですが、色深度を変えようとしたりすると ImageMagick 6 と 7 では差がでますのでご注意ください #892

imagemagick formula のアップデート方法(備忘録)

RMagick が ImageMagick 7 に対応しそうなのだが Homebrew で提供されているバージョンだとビルドに失敗するので、アップデートをリクエストした。

やっていることは、ほぼ imagemagick@6 formula のアップデート方法(備忘録) - @watson1978 の日記 とおなじ。

$ export IMAGEMAGICK_VERSION="7.0.9-26"
$ curl -O https://imagemagick.org/download/releases/ImageMagick-$IMAGEMAGICK_VERSION.tar.xz
$ export SHASUM256=`shasum -a 256 ImageMagick-$IMAGEMAGICK_VERSION.tar.xz | awk '{print $1}'`

$ cd $(brew --repository homebrew/core)
$ brew bump-formula-pr imagemagick --strict \
--url=https://dl.bintray.com/homebrew/mirror/ImageMagick-$IMAGEMAGICK_VERSION.tar.xz \
--mirror=https://www.imagemagick.org/download/releases/ImageMagick-$IMAGEMAGICK_VERSION.tar.xz \
--sha256=$SHASUM256