I am writing a 64 bit F# solution and profiling has revealed a surprisingly & unexpectedly large amount of time spent in JIT_TailCall
...it is in fact dominating the runtime (circa 80%). This appears together with its evil cousin JIT_TailCallHelperStub_ReturnAddress
.
I have definitely traced the source to passing a struct
type (custom value types) in a method or property call across an assembly boundary. I am certain of this because if I bypass the method call and assign my struct
to the property directly (the one the offending method was using) the performance magically improves by a factor of 4-5 x less runtime!
The calling assembly is using F# 3.1 because it is being dynamically compiled with the latest stable release of FSharp.Compiler.Services.
The assembly being called is using F# 4.0 / .NET 4.6 (VS 2015).
UPDATE
A simplification of what I am trying to do is to assign a custom struct
value to a position in an array from a dynamically generated assembly...
Runtime is fast and no extraneous tail calls are generated when calling:
- A property exposing the private array in the type
However, the runtime is slow due to extraneous tail calls being generated when calling:
An indexer property exposing the array (Item)
A member method acting as a setter for the array
The reason I need to call the member method is that I need to perform a few checks prior to insertion of the item in the array.
PRACTICAL
Over and above understanding the root of the issue, I would like to know whether F# 4.0 and by implication the coming release of FSharp.Compiler.Services would solve this issue. Given that the updated FSharp.Compiler.Services is relatively imminent, it may then just be best to wait.
JIT_TailCall
and 15% load forJIT_TailCallHelperStub_ReturnAddress
. This functions are closed over method variables and a class fields. When I turn off the tail call generation, my performance increases exactly by 45%. Thanks for the suggestion to turn it off. Starting to rewrite the recursion as loop... – Samoyed