有代码读取 IORef 并根据一些条件和计算创建一个新值。现在它将新值写入该 IORef。但它有可能根本没有改变。新值可能与旧值相同。
在写入 IORef 之前是否检查值是否不同,或者不管是否只写入 IORef,有哪些注意事项?
writeIORef 是否在设置之前检查值是否已更改?
通过首先检查,您是否可以避免写入并节省一点性能?
writeIORef 是否在设置之前检查值是否已更改?
编号writeIORef
wraps 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 的人类可读生成的输出 (Core),因为这样您就可以做出这些决定(在一个非常精细的级别)在每个程序的基础上。