【问题标题】:Should check for change before writing IORef?在编写 IORef 之前应该检查更改吗?
【发布时间】:2011-06-14 09:48:32
【问题描述】:

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

在写入IORef之前是否检查值是否不同,或者直接写入IORef,有什么注意事项?

writeIORef在设置前是否检查值是否改变?

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

【问题讨论】:

    标签: haskell reference ioref


    【解决方案1】:

    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's human-readable generated output (Core),因为这样您就可以做出这些决定(在非常细粒度的级别上)在每个程序的基础上。

    【讨论】:

    • 另外一个注意事项是:由于 IORef 的内容只是一个指针,因此写入它是快速。将其内容的值与新值进行比较是相当昂贵的。
    猜你喜欢
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    相关资源
    最近更新 更多