有代码读取IORef并根据某些条件和计算创建一个新值。现在它将新值写入IORef。但它有可能根本没有改变。新值可能与旧值相同。
在编写IORef之前是否要检查价值是否不同,或者只是写IORef,有什么考虑?
writeIORef在设置之前是否检查值是否已更改?
首先检查一下,你可以避免写入并节省一点性能吗?
答案 0 :(得分:8)
writeIORef在设置之前是否检查值是否已更改?
没有。 writeIORef
换行writeSTRef
,定义为
-- |Write a new value into an 'STRef'
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef (STRef var#) val = ST $ \s1# ->
case writeMutVar# var# val s1# of { s2# ->
(# s2#, () #) }
首先检查一下,你可以避免写入并节省一点性能吗?
在编写IORef之前是否要检查价值是否不同,或者只是写IORef,有什么考虑?
这实际上取决于所讨论的算法。你想要优化什么?读写的频率/比率是多少?你存储什么样的数据?怎么包装好?相关数据的平等比较成本是多少?
在确定是否要在适当位置破坏性地更新单元时,需要考虑许多因素:某些算法特定,一些取决于缓存局部性,另一些取决于代码的结构和形式GHC产生。因此,回答你的问题非常困难。
Donald Knuth的一句话:
我们应该忘记小的效率,比如大约97%的时间:过早的优化是所有邪恶的根源
除非你正处于试图从一些易于理解的实现中找出每一小部分性能的阶段,否则你最好选择路径
继续吧。如果你 在你想要调整你的程序的阶段,我建议你学习阅读GHC's human-readable generated output (Core),因为你可以做到这一点。决策(在非常精细的层面上)基于每个程序。