I spent several days last week trying to track a cause of a 100%
slowdown after some trivial changes I made. The profiler didn't show any
slowdown, presumably because it was dependent on optimizations, so I had
to revert to tweak-run-measure cycle.
It turned out the slowdown was caused by some unevaluated thunks
that were kept around in long-lived IORefs. This is not the first time I
was bitten by too laziness, either. What made things worse this time is
that there is no way do declare the following:
data Label = LabelRef {labelId:: !Unique,
reference:: (IORef !LabelState), -- illegal
origin:: Maybe !Label} -- illegal
No container data type can be annotated as strict. That means I have
to pepper my code with explicit evaluations to HNF before every
writeIORef (reference label):
newState `seq` writeIORef (reference label) newState
What is the reason for this restriction on where strictness
annotations can appear? Is it purely an implementation problem or is
there a reason emanating from Haskell design? If former, how hard would
it be to fix?