Skip to content

A more efficient atomicModifyIORef'

atomicModifyIORef' is currently defined as:

atomicModifyIORef' ref f = do
    b <- atomicModifyIORef ref
            (\x -> let (a, b) = f x
                    in (a, a `seq` b))
    b `seq` return b

This doesn't seem to be the best we can do, though.

The following implementation exhibits a speedup of 1.7x (vanilla RTS) / 1.4x (threaded RTS) over the current implementation:

atomicModifyIORef' ref f = do
    b <- atomicModifyIORef ref $ \a ->
            case f a of
                v@(a',_) -> a' `seq` v
    b `seq` return b

The differences between this version and the current version are:

  1. the lambda is now strict in f a, and
  2. a new result tuple is no longer being allocated.

Is there a good reason why atomicModifyIORef' is not already defined this way?

Trac metadata
Trac field Value
Version 7.6.3
Type Task
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC joeyadams
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information