让 EQUALP 下的数字哈希既正确又高效:ECL 的三轮优化
来源:turtleware.eu — 2026-10-26
📋 概述
作者在给 ECL 优化泛函数派发时顺手重做了哈希表与哈希函数,撞上一个别扭的老问题:Common Lisp 的 EQUALP 认为 1 和 1.0、1/2 和 0.5、42 和 #C(42.0 0.0) 相等,所以哈希函数必须给它们同一个值。一致性要求只是下限——把所有数字哈希成常数虽然合规,但哈希表会退化成链表。文章从最简单的基线模型出发,经两轮实现修正,最后落到一个可解释的二分模型:既不因为偷懒丢精度,也保证除真正相等的数以外都走不同路径。
🔑 核心要点
- 合规的底线是 相等则同哈希,反向不成立——同哈希不必相等,所以「全部返回 42」是合法的,但性能上毫无意义
- 麻烦来自 EQUALP 的跨类型相等判定:(equalp 1 1.0) 为真、(equalp 1/2 0.5) 为真、(equalp 42 #C(42.0 0.0)) 也为真
- 第一轮实现咬在 数值塔上——有理数、单双精度浮点、复数各有表示形式,要统一到同一等价类
- 最终模型是 二分:不做有损转换丢精度,同时保证除相等数外都走不同哈希路径
- 收益是实测的:哈希表与泛函数派发的基准全面变快,EQUALP 混合键与随机插入删除场景都受益
- 作者顺带给出方法论:先用简单基线模型,再改实现,最后用更优雅的概念模型解释它,然后把优化与验证做成闭环
💡 金句
hashing can be lossy, but it can't be inconsistent with the test
👍 0
👎 0
← 返回 Lobsters 首页