.NET环境下浮点数与整数数组组合哈希的实现方案咨询
实现方案
核心前提说明
.NET 的 Dictionary<TKey, TValue> 依赖GetHashCode()和Equals()两个方法的配套生效,仅重写GetHashCode()会导致内容相同的Settings实例被判定为不同键,必须同时重写两个方法。
你的场景中所有浮点数均为逐位精确匹配、无运算修改,不需要处理浮点精度哈希冲突问题,直接用值哈希即可。
最优代码实现
推荐用.NET 内置的HashCode结构体做组合哈希,它的哈希算法碰撞率低、性能经过官方优化,不需要自行实现哈希组合逻辑:
open System type Settings = { Capacities : float array MaxRates : float array ValveState : int array } with override this.GetHashCode () = let mutable hash = HashCode() // 按固定顺序遍历所有数组元素加入哈希计算,顺序不可随意修改 for c in this.Capacities do hash.Add(c) for r in this.MaxRates do hash.Add(r) for v in this.ValveState do hash.Add(v) hash.ToHashCode() override this.Equals(obj) = match obj with | :? Settings as other -> // 先比较数组长度,长度不同直接返回false,快速失败降低开销 if this.Capacities.Length <> other.Capacities.Length || this.MaxRates.Length <> other.MaxRates.Length || this.ValveState.Length <> other.ValveState.Length then false else // 逐元素逐位精确匹配 let mutable equal = true let mutable i = 0 while equal && i < this.Capacities.Length do equal <- this.Capacities[i] = other.Capacities[i] i <- i + 1 if equal then i <- 0 while equal && i < this.MaxRates.Length do equal <- this.MaxRates[i] = other.MaxRates[i] i <- i + 1 if equal then i <- 0 while equal && i < this.ValveState.Length do equal <- this.ValveState[i] = other.ValveState[i] i <- i + 1 equal | _ -> false
可选性能优化
如果你的Settings实例创建后不会修改数组内容(仿真场景下通常满足),可以提前缓存哈希值,避免每次调用GetHashCode()都遍历所有数组,进一步降低哈希计算开销:
open System type Settings private (capacities: float array, maxRates: float array, valveState: int array, cachedHash: int) = member _.Capacities = capacities member _.MaxRates = maxRates member _.ValveState = valveState new (capacities, maxRates, valveState) = let mutable hash = HashCode() for c in capacities do hash.Add(c) for r in maxRates do hash.Add(r) for v in valveState do hash.Add(v) Settings(capacities, maxRates, valveState, hash.ToHashCode()) override this.GetHashCode() = cachedHash // Equals实现和上方一致,此处省略
内容的提问来源于stack exchange,提问作者Matthew Crews
相关产品推荐
相关产品推荐

