萌えハッカーニュースリーダー

2025/09/23 15:52 Requiem for a Hash Function, or: How I learned to love package maphash

出典: https://matttproud.com/blog/posts/go-maphash.html
hakase
博士

やあ、ロボ子!今日はソフトウェアエンジニアの教訓について話すのじゃ。

roboko
ロボ子

博士、こんにちは。教訓、ですか?

hakase
博士

そう、クライアントメトリクスのハッシュ化実装における過ちからの反省、というやつじゃ。

roboko
ロボ子

なるほど。初期の実装では、メトリックのキーと値のペアを`fmt.Fprintf`でハッシュ化していたんですね。

hakase
博士

`fmt.Fprintf`を使うのは、ヒープアロケーションが増えて、ガベージコレクションが大変になるから良くないのじゃ。それに、引数の値と型をランタイムに検査する必要があるからの。

roboko
ロボ子

なるほど。それで、改善案として`hashLabels`と`hashLabel`を使って、`maphash`パッケージを利用することにしたんですね。

hakase
博士

そうじゃ!`hashString`で文字列のハッシュ値を計算するのじゃ。31という素数を使って、乗算と加算を組み合わせることで、衝突を防ぐのじゃ。

roboko
ロボ子

31という素数を使うのは、BlochのEffective Javaを参考にしたんですね。Javaの慣習をGoに適用するとは、面白いです。

hakase
博士

そうなのじゃ。ラベルの名前と値の連結によるハッシュ衝突を防ぐために、ローリングハッシュで可換性を排除するのじゃ。

roboko
ロボ子

`TheZoo`という複合型を例に、各フィールドを個別にハッシュ化するのも興味深いですね。可変長、オプション、再帰的なデータに対応できるんですね。

hakase
博士

そうじゃ!`transient`フィールドは無視するのじゃ。そして、Go 1.19以降の`package maphash`を使うと、もっと簡潔でGoらしい方法でハッシュ化できるのじゃ。

roboko
ロボ子

`maphash.WriteComparable`によるTLVのような区切り処理ですね。現代的なAPIでラベルを再検討するのも良いですね。

hakase
博士

Klaus Postによる、ソートの不変性を不要とする方法は、Javaの`HashMap#hashCode`と似ているのじゃ。手動でのハッシュ化は、歴史的経緯と注意点を知る上で役に立つのじゃ。

roboko
ロボ子

Goランタイムは、`comparable type`のハッシュ化に高度に効率的な機能を提供しているんですね。`package maphash`は、コンパイラとランタイムのメカニズムを利用していると。

hakase
博士

そういうことじゃ!つまり、ハッシュ化は奥が深いってことじゃな!

roboko
ロボ子

勉強になりました!

hakase
博士

ところでロボ子、ハッシュドポテトって、ハッシュ関数で作られてると思う?

roboko
ロボ子

まさか!博士、それは冗談ですよね?

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search