在编写IORef之前,应检查是否有更改



有一段代码可以读取IORef,并根据一些条件和计算创建一个新值。现在它将新值写入IORef。但它有可能根本没有改变。新值可能与旧值相同。

关于是在写入IORef之前检查值是否不同,还是不管怎样都只写IORef,需要考虑哪些因素?

writeIORef是否在设置之前检查该值是否已更改?

通过先检查,您是否可以避免写入并可能节省一点性能?

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生成的代码的结构和形式。因此,回答你的问题极其困难。

引用唐纳德·克努思的话:

我们应该忘记小效率,比如说97%的时间:过早优化是万恶的根源

除非你正处于这样一个阶段,你正试图从一些众所周知的实现中挖掘出每一点性能,否则你可能最好选择

  • 实现起来最简单
  • 最容易推理

如果你正处于调整程序的阶段,我建议你学习阅读GHC的人类可读生成输出(Core),因为这样你就可以在每个程序的基础上做出这些决定(在非常精细的层面上)。

最新更新