RHG 片手に Ruby 1.9 を読む集い(The RHG Strikes Back)に参加した(2) - 第2回 RHG の逆襲
メモリ節約のための Pack
Ruby 1.9 から、st_table 構造体に entries_packed という変数が追加されました。これは、pack されているかどうかを示すフラグですが、pack されている場合、st_table_entry 構造体を作成せず、配列に key と value を交互に詰めていきます。つまり、ハッシュというよりは単なる配列になるわけです。
もともと、ハッシュテーブルを使う理由は、キーに対応する値を取り出す際に、配列や線形リストを単純に操作すると計算量が増えるためです。要素数が少ない場合、ハッシュテーブルを使うコストの方が大きくなってしまうという指摘があるようです。
ruby-dev の議論によると、要素数 3 以内の場合にメモリ節約と高速化の面で packed の効果は顕著なようです。
この辺の議論では、吉岡さんから packed の高速化の要因として配列に値を埋め込む方が CPU のキャッシュヒット率が上がるのではないかという指摘もありました。(ただし、定性的に説明することはできても、ベンチマークを取ってみないとわからないという話もされていました。)
ハッシュ値を散らすための疑似乱数
ハッシュ関数でハッシュ値を計算する際に、FNV1_32A_INIT(st.c の strhash 関数)という定数が登場します。このハッシュ関数ではハッシュ値を散らすために Xorshift 法による疑似乱数生成ルーチンが使われており、この定数はそこから来ているようです。(ハッシュ値が衝突すると、リストを手繰らないといけないため、ハッシュ値は散る方が都合がいいのです。)
この点についてはこちらで詳しく触れられています。
Ruby 1.9 からはハッシュの順番を保持するようになった
Ruby 1.8 までは、ハッシュテーブルに格納された要素は格納した順番を保持しなかったのですが、今は格納するようになりました。st_table_entry(st.c)の fore, back という変数を参照してください。
ハッシュテーブルに含まれるエントリの順番(by Kodougu)
m17n はややこしい
文字列と ID(文字列と一対一で対応する数値)を変換する仕組み(rb_intern 関数参照)では、m17n なども絡むため、理解しにくい部分があります。m17n は Ruby 1.9 で開発が活発な部分でもあるため、後ほど回を改めて勉強をすることになりました。(いつ頃になるかは不明。)
次回勉強会の予習の指針
最後に yugui さんから次回予習の指針が示されました。次回のメインテーマは Ruby のクラスをどのように定義するか、メタクラスを含めた構造がどのようになっているかです。RHG 的に言うと「第4章 クラスとモジュール」に相当します。
抑えておいた方が良いと思われるものとして、io.c の最下部にある io 関連のクラスの定義や object.c 内の「Document-class: Class(2300 行前後)」にある Ruby のクラスの基本構造(同種の図は RHG 4 章にもある)、モジュールのインクルードが継承的に見てどのように取り扱われているかなどが挙げられました。
まとめ
発表終了後は懇親会を行い、無事に勉強会は終了しました。勉強会の細かいログは rhg-strikes-back (at Lingr) にも掲載されているので、ぜひご参照ください。
主催者の皆様、有意義な勉強会をありがとうございました。次回も参加することができたら、本ブログで紹介したいと思います。それでは!
1 2
このサイトについて
TrackBack URL :
