Description
I work a lot with Task<bool>
, whose two possible valid results could be cached. I added a simple logic:
match continuation() with
| Return r ->
if typedefof<'a> = typedefof<bool> then
let rb : bool = unbox(box(r))
if rb then
methodBuilder.SetResult(unbox(box(TaskUtil.TrueTask)))
else
methodBuilder.SetResult(unbox(box(TaskUtil.FalseTask)))
else
methodBuilder.SetResult(Task.FromResult(r))
null
If that was written in C#, then JIT would treat typedefof<'a> = typedefof<bool>
as JIT-time constant and completely eliminate branch. Should we use typedefof
or typeof
for this? Also C#'s version (T)(object)(value)
doesn't cause object
allocation for value types since JIT is smart enough to recognize such pattern.
Will those JIT optimizations work for the code above? So that the line let rb : bool = unbox(box(r))
doesn't allocate. Or if it does, how to avoid allocations in F# for such a cast? (I will test later myself, just wanted to discuss/review).
Also (not related, but small for a separate issue) I noticed that on the line let methodBuilder = AsyncTaskMethodBuilder<'a Task>()
the type AsyncTaskMethodBuilder
is mutable struct but here it is stored in an immutable variable. Is this intentional or the thing works now by chance and doesn't use methods that mutate the struct? There are comments in the source about mutability.