
Hello, One thing I discovered a while ago when fiddling about with optimisting the AVL library was that making the AVL constructors strict in left and right sub-tree fields resulted in slower code than using no strictness annotation and explicit forcing of evaluation with `seq`. I hope it isn't too presumptious of me to hazard a guess as to what might cause this :-) My guess is that it's because the AVL code contains a lot of stuff like this.. -- With strictness annotations case blah of N l e r -> N l e (f r) -- l and r are left and right sub-trees or -- Without strictness annotations case blah of N l e r -> let r' = f r in r' `seq` N l e r' Now if the compiler wasn't smart enough to figure out that in the first example l was already reduced (because it's from a strict field) then it would get diverted trying to reduce it again (pointlessly accessing heap record it didn't need, disrupting the cache etc), so the net result would be slower code. But in truth I understand precious little about what analyses and optimisations ghc is capable of, so this could all be complete nonsense. So is this explanation plausible? Also (persuing this a little further) it occurs to me that the if this hypothesis is correct there could be other bad effects. For example, if in an expression I have a constructor with a strict field, but the constructor is used in a non-strict context. Presumably the compiler won't generate this constructor in it's "reduced form" (whatever that might be for ghc :-) because this would force evaluation of the field value. So it must construct some kind of thunk instead. But there's no reason it should be so inhibited if the constructor was non-strict (or if the compiler could figure out the field value was already reduced). Thanks -- Adrian Hey
participants (1)
-
Adrian Hey