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.
I work a lot with
Task<bool>, whose two possible valid results could be cached. I added a simple logic:If that was written in C#, then JIT would treat
typedefof<'a> = typedefof<bool>as JIT-time constant and completely eliminate branch. Should we usetypedefofortypeoffor this? Also C#'s version(T)(object)(value)doesn't causeobjectallocation 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 typeAsyncTaskMethodBuilderis 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.