Skip to content

Add opt-in performance group with STM-avoidance hints#1690

Open
mgajda wants to merge 1 commit intondmitchell:masterfrom
mgajda:performance-stm
Open

Add opt-in performance group with STM-avoidance hints#1690
mgajda wants to merge 1 commit intondmitchell:masterfrom
mgajda:performance-stm

Conversation

@mgajda
Copy link
Copy Markdown

@mgajda mgajda commented Apr 20, 2026

Summary

Add a new performance group (disabled by default) that flags single-primitive uses of STM where a non-transactional primitive from Data.IORef / Control.Concurrent.MVar / Control.Concurrent.Chan / Control.Concurrent.QSem gives the same operation at a fraction of the cost.

The transaction log, commit-time validation, and retry machinery are pure overhead when a transaction touches a single variable and needs no composition. Students toggle the group off (the default); users who care about per-access overhead opt in with --with-group=performance.

What's covered

  • TVar: atomically (readTVar/writeTVar/modifyTVar/modifyTVar'/swapTVar/stateTVar v), readTVarIO, newTVarIOreadIORef / atomicWriteIORef / atomicModifyIORef' / newIORef.
  • TMVar: the full takeTMVar / putTMVar / readTMVar / tryTakeTMVar / tryPutTMVar / tryReadTMVar / swapTMVar / isEmptyTMVar / newTMVarIO / newEmptyTMVarIO family → MVar equivalents.
  • TChan: readTChan / writeTChan / dupTChan / newTChanIOChan equivalents.
  • TQueue: readTQueue / writeTQueue / newTQueueIOChan equivalents.
  • TSem: waitTSem / signalTSem / newTSemQSem equivalents.

What's deliberately not covered

  • Multi-variable atomically $ do { ... } transactions.
  • retry / orElse / check.

Tests done

  • hlint --test — 965 tests pass.
  • New tests/flag-with-group-performance.test exercises three hints (writeTVar/takeTMVar/writeTChan) under --with-group=performance.
  • Asample module with both single-primitive STM and a multi-TVar transfer transaction: the first got eight hints, the second got zero (correct).
  • Default mode: only the pre-existing readTVarIO/newTVarIO hints fire (no new noise).

New group (enabled: false) flags single-primitive uses of STM where a
non-transactional primitive from IORef/MVar/Chan/QSem gives the same
operation at a fraction of the cost: the transaction log, commit-time
validation, and retry machinery are pure overhead when a transaction
touches a single variable and needs no composition.

Hints cover TVar, TMVar, TChan, TQueue, and TSem. Multi-variable
transactions correctly do not match (no false positives on genuinely
composable STM).

Activate with `--with-group=performance`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant