[Mew-dist 09776] Re: hash on Emacs (toward threading)
Shigeya Suzuki
shigeya at example.com
1999年 7月 20日 (火) 00:01:47 JST
>>>>> "kazu" == 山本和彦 <Kazu> writes:
kazu> Emacs の変数や関数の値の検索にはこの obarray が利用されています。実際
kazu> に obarray という大域変数があるので、評価してみるといいでしょう。この
kazu> obarray の大きさは 1511 に決め打ちされています。
1511 って prime で、恣意的に選んだ値だと思います。
% /usr/games/factor 1511
1511: 1511
kazu> ここで湧く疑問は、Emacs がたくさん .el を読み込むと、衝突が頻繁に起こ
kazu> り、線形検索の部分が遅くなるのではないかということです。ソースを見た限
kazu> り、ハッシュを動的に大きくするなどの作業はしていないようです。この理解
kazu> は正しいでしょうか?
kazu> ここから本題ですが、obarray を使うと簡易 DB が作成できるので、thread
kazu> を実装する際に役に立ちます。(Message-ID: に対し、In-Reply-To: を登録す
kazu> るなど。)しかし、メッセージの数が大きくなると効率が落ちるんじゃないで
kazu> しょうか? 真剣に探しましたが、ハッシュを大きくする方法はないようです。
...
kazu> あと、ハッシュに関して深い知識のある方は、ハッシュはどういうときに大き
kazu> くすべきか教えてもらえると嬉しいです。
深い知識というわけではないけど、そもそも、hash 関数にあった bucket
size ってのがあると思うので、この配列の大きさかえても、関数自体が変わ
らないと意味ないかも。
結局、hash のキーに当たる値から、キーにhash関数を適用したときに、適当
に値が分散するようなhash関数が良いわけで、むやみにbucket sizeを多くし
ても、hash関数自体が対応するものでなければ意味無いでしょう。適度にばら
けていて、かつ、範囲がコンパクトな方が良いでしょう。
あのへんみてるなら、とうぜん見てると思いますが、Emacsのhash関数は、こ
んなんです。これを1511で割ってる。
static int
hash_string (ptr, len)
unsigned char *ptr;
int len;
{
register unsigned char *p = ptr;
register unsigned char *end = p + len;
register unsigned char c;
register int hash = 0;
while (p != end)
{
c = *p++;
if (c >= 0140) c -= 40;
hash = ((hash<<3) + (hash>>28) + c);
}
return hash & 07777777777;
}
まあ、キーになる値のパターンが変わると、適正な関数とかも変わると思うけ
れど、Message-ID ぐらいの値のふれかただと、最後が com/gov/orgとか jp
とかあるから、最後の数回のループの値の適用パターンが同じになるから、少
しふれかたが固まるかもしれない。(hash>>28)が、どれだけきくかにかかって
いるかもしれないが、日付とかもエンコードされているのが裏目にでるかもし
れないし。。実際にデータくわせてみないとわからないかも。
あと、Emacs とは関係ないけれど、ヘタにhash関数使うより、昨今のアーキテ
クチャに、そこそこ賢いコンパイラの組み合わせだと、単純なリニアサーチの
方が早かったりします。(ばかっぱやだから) なので、ヘタに凝ったhash関数
作ると失敗します。
結局、どういう文字列を、どのぐらいの長さで、かつ、最終的なレコード数が
何レコードぐらいになるのかのバランス考えないと、良いとか悪いとかは言え
ない。で、間を取ると↑ぐらいになるってことなのではないかと。
僕がこの手の関数作る場合は、ターゲットのキーになる値を実際の関数にかけ
て、振れ具合いみて決めてます。漢字とか混ざっている場合、漢字コードによっ
ても振れ具合いは変わるし(笑) もっとサボっても平気そうなら、手を抜きま
す。
私見としては、Message-ID に対するハッシュ関数というのは、工夫の余地が
比較的低い(かなり傾向があるし、時間的な分散具合いもイヤ)ので、普通の
関数つかう以外に方法ないんじゃないかという気がします。
shigeya
Mew-dist メーリングリストの案内