Crystal中向Hash插入键时避免两次哈希并检测覆盖的最优方案是什么
Crystal Hash插入重复键报错的最优实现
你用到的Hash#put带块的写法本身就是官方支持的性能最优的实现,全程仅执行1次哈希计算,没有额外性能损耗。如果觉得可读性不足,可以采用以下两种优化方案:
方案1:扩展Hash类封装语义化方法(最推荐)
可以给Hash自定义语义明确的实例方法,在不损失性能的前提下大幅提升可读性:
class Hash(K, V) # 仅当key不存在时插入对应value,key已存在则抛出错误 def put_new!(key : K, value : V, error_msg = "Mapping already exists for key: #{key}") if put(key, value) {} raise error_msg end end end
调用方式非常简洁:
map = Hash(String, Int32).new map.put_new!("foo", 42)
方案2:保留原生写法加注释
如果不想对Hash做全局扩展,可以直接保留你现有的写法,补充一行注释说明逻辑即可:
map = Hash(String, Int32).new # put带空块逻辑:键存在返回旧值抛错,键不存在插入值返回nil if map.put("foo", 42) {} raise "Mapping already exists" end
不推荐的替代写法
注意不要采用has_key?判断后再赋值的写法,这种写法会执行2次哈希计算,性能低于上述方案;也不要用fetch结合赋值的写法,同样会产生两次哈希操作。
内容的提问来源于stack exchange,提问作者Philipp Claßen
相关产品推荐
相关产品推荐

