ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

Uzumibi 0.3 のリリース

リリースした。往生際悪く(?)ブログを書く。


続きを読む

mruby/edgeで使うSipHashとFNVをかるっと比較

開発メモが流行ってるらしいので...、茶飲み話でも残すか...。

mruby/edge のHash

実装方針はこうしている:

  • 基本、標準のHashMapをそのまま使う
  • キーに関しては、オブジェクトごとに Hash トレートを実装してそれを使わせればいいじゃない...

ところでRustのHashMapはデフォルトでSipHashというものを使う。良い説明記事があるのでそちらにデリゲートしますね...。

zenn.dev

記事の通り、秘密鍵(ランダムネス)を用いるので推測されづらく、あと、アルゴリズムもシンプルで高速。

これでいいじゃん、なのだが、 FNV というハッシュアルゴリズムもあり、もっと小さいアプリケーションならこっちも使えないかと思って軽く試したというメモです。

FNV (実装は FNV-1a になってそう)はservoが作ってるやつがあって、小さいし、HashMapやHashSetの実装も添付していて、そのインタフェースは set(&K: Hash, V) とかで一緒になっているのでこれをそのまま使えばよし。

github.com

こんな感じでfeature flagで丸ごと別名を切り替えればそのまま使える(FnvHashMap::new() はないので、 FnvHashMap::default() を使う)

#[cfg(feature = "mruby-hash-fnv")]
pub type RHashMap<K, V> = fnv::FnvHashMap<K, V>;
#[cfg(feature = "mruby-hash-fnv")]
pub type RHashSet<K> = fnv::FnvHashSet<K>;
#[cfg(feature = "mruby-hash-fnv")]
pub type RHash = fnv::FnvHashMap<ValueHasher, (Rc<RObject>, Rc<RObject>)>;
#[cfg(not(feature = "mruby-hash-fnv"))]
pub type RHashMap<K, V> = std::collections::HashMap<K, V>;
#[cfg(not(feature = "mruby-hash-fnv"))]
pub type RHashSet<K> = std::collections::HashSet<K>;
#[cfg(not(feature = "mruby-hash-fnv"))]
pub type RHash = std::collections::HashMap<ValueHasher, (Rc<RObject>, Rc<RObject>)>;

ベンチ(単純にHashMap使う)

コードはpushしてある。ログは以下に抜粋:

default HashMap 10000 entries (1 char keys)
                        time:   [390.10 µs 390.54 µs 391.07 µs]

FNV HashMap 10000 entries (1 char keys)
                        time:   [338.16 µs 338.67 µs 339.22 µs]

default HashMap 10000 entries (5 char keys)
                        time:   [677.13 µs 677.60 µs 678.25 µs]

FNV HashMap 10000 entries (5 char keys)
                        time:   [550.01 µs 550.58 µs 551.34 µs]

default HashMap 10000 entries (10 char keys)
                        time:   [687.46 µs 688.55 µs 689.99 µs]

FNV HashMap 10000 entries (10 char keys)
                        time:   [604.11 µs 604.66 µs 605.48 µs]

default HashMap 10000 entries (20 char keys)
                        time:   [785.55 µs 790.05 µs 796.93 µs]

FNV HashMap 10000 entries (20 char keys)
                        time:   [806.96 µs 807.76 µs 808.73 µs]

default HashMap 10000 entries (50 char keys)
                        time:   [906.43 µs 911.02 µs 919.24 µs]

Benchmarking FNV HashMap 10000 entries (50 char keys): Warming up for 3.0000 s
FNV HashMap 10000 entries (50 char keys)
                        time:   [1.3509 ms 1.3520 ms 1.3536 ms]

Benchmarking default HashMap 10000 entries (100 char keys): Warming up for 3.0000 s
default HashMap 10000 entries (100 char keys)
                        time:   [1.1861 ms 1.2035 ms 1.2243 ms]

FNV HashMap 10000 entries (100 char keys)
                        time:   [2.4353 ms 2.4458 ms 2.4575 ms]

グラフです:

ベンチ(mruby/edgeの中で使った時

※ mruby/edgeの中で使っているHashMapは全部FNVに変えています

僕はこう思ったっす

  • キー長が10文字前後まではFNVの方が割と高速だったりする
  • 一方Hashするデータ数が大きいと劣化が目立つのはFNV
  • え、SipHash優秀じゃん...
  • しかし正直、普通に計測するとStringの生成とかの方がオーバヘッドになってたので(String使い回すように変えた)、あれ

結局、一応gem(feature flag)としては使い分けられるようにした。結構短いHashのキーしか使わないアプリケーションもあるかもしれない。

しかし、ランタイムも自分で作っていると、こういうふうにアルゴリズムで遊べるのはいい話か。

ちなみに安全性について

Rustのwasm32-unknown-unknownのような環境ではそもそもランダムネスを取得できないよなと思って軽くコードを見たら、以下の感じで:

github.com

システムコールが呼べないtargetではアドレスをソースに使うらしい。そうか〜という気持ちです。

また、キーのハッシュ関数にFNVを使う場合は、現実的にはsaltでも含めるといいのかなと思われる。そういうインタフェースを持たせたほうがいいかもではある。

Uzumibi: あらゆるエッジでRubyを動かすために

明けましておめでとうございます。

Uzumibi (埋み火)と言う、あらゆるエッジでRubyを動かすためのウェブフレームワークを作っています。この度RC版を出したので使い方を共有します。

github.com

What is Uzumibi

Uzumibi は各種エッジコンピューティングサービスでRubyのアプリケーションを動かしたい時に使うフレームワークです。

詳細はこういう雰囲気です。

  • ひとまず、 Cloudflare WorkersFastly ComputeSpin(Fermyon Cloud)をサポートした*1
  • Rubyランタイムは mruby/edge を利用(なのでまだそもそも機能が少ない...)
  • mruby/edgeを丸っと含んだWebAssemblyバイナリを作って動かします

mruby/edge 自体については、2024年に発表していました。当時はこれはRubyと言えるか怪しかったのですが、その後色々改善し、2年かけて応用例を公開できてよかったです。

rubykaigi.org

ところで同じく日本語で炎っぽい...名前の...各種エッジで動くフレームワークがありますが、若干は影響を受けてるかもしれません*2

*1:Fermyonがついこの間Akamaiに買われたので、結果的に3大CDNをサポートしてるみたいになった

*2:Hono + Embedded で Uzumibi というのも由来の一つではある

続きを読む

PHPカンファレンス福岡2025で登壇しました! feat. 私とPHPカンファレンス福岡

PHPカンファレンス福岡について語ってほしい! Advent Calendar 2025 の10日目の記事です。公開が遅くなり、申し訳ありません!

adventar.org

少し前になりますが、11月8日に開催された「PHPカンファレンス福岡2025」に登壇してきました。

phpcon.fukuoka.jp

遅ればせながらではありますが、この記事ではカンファレンス当日や登壇内容の紹介をします! 一緒に、福岡のエンジニアコミュニティという観点から福岡におけるPHPカンファレンスを振り返ってみたいと思います。

続きを読む