在写IORef之前应该检查一下变化吗?

men*_*ics 3 haskell reference ioref

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

关于在编写IORef之前是否检查值是否不同,或者只是编写IORef,需要考虑哪些因素?

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

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

Rae*_*eez 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#, () #) }
Run Code Online (Sandbox Code Playgroud)

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

关于在编写IORef之前是否检查值是否不同,或者只是编写IORef,需要考虑哪些因素?

这实际上取决于所讨论的算法.你想要优化什么?读写的频率/比率是多少?你存储什么样的数据?怎么包装好?相关数据的平等比较成本是多少?

在确定是否要在现场破坏性地更新单元时,需要考虑许多因素:某些算法特定,一些取决于缓存局部性,另一些取决于GHC生成的代码的结构和形式.因此,回答你的问题非常困难.

唐纳德克努特的一句话:

我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源

除非你正处于试图从一些易于理解的实现中找出每一小部分性能的阶段,否则你最好选择一条路径.

  • 最简单的实施
  • 最容易推理的

并继续它.如果您处于调整程序的阶段,我建议您学习阅读GHC的人类可读生成输出(Core),因为您可以做出这些决定(在一个非常精细的级别)基于每个程序.

  • 另外一个注意事项是:由于IORef的内容只是一个指针,因此写入它是*fast*.相比之下,将其内容的值与新值进行比较是相当昂贵的. (4认同)