id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	os	architecture	failure	difficulty	testcase	blockedby	blocking	related
5916	runST isn't free	tibbe		"While optimizing some code I discovered that `runST` isn't free. I had a function on the form:

{{{
f ... = ...let x = runST in (f x)...
}}}

Manually transforming it into

{{{
f ... = runST (g ...)
 where g ... = do
    ...
    x <- ...
    g x
    ...
}}}

(The real example is at https://github.com/tibbe/unordered-containers/commit/58b7815a057b3575c58b746d5971d59d806b1333)

improved performance quite a bit on this, already highly tuned, function. Unfortunately, combining all the calls to `runST` into one and pulling them ""up"" is not all good. The code is now less modular, has a somewhat over specified evaluation order, and generally looks more imperative.

The cause of the decrease in performance is that `runSTRep` cannot be inlined, which causes allocation of closures inline in the code (where none should be necessary.)

The comment next to `runSTRep` explains why it's implemented the way it is, but I wonder if matters could be improved by making it a primop. If we create a fresh state token every time, instead of reusing `realWorld#`, it should be impossible for mutable structures to let-float and become CAFs (which is what `runSTRep` tries to avoid.)"	bug	new	normal	7.6.2	Compiler	7.4.1			carter.schonwald@…	Unknown/Multiple	Unknown/Multiple	None/Unknown	Unknown				
