While doing some profiling on one of our applications, I found this code:
public TOut GetValue<TIn, TOut>(Func<TIn> getter)
{
var value = getter();
// Do some stuff with the value
return (TOut)Convert.ChangeType(value, typeof(TOut));
}
TIn
and TOut
are either int, double, or string.
This showed up in the profiling sessions as an important source of heap allocations because of the boxing when using int or double. The input value of Convert.ChangeType
is boxed because the method expects an object, and the return value is boxed for the same reason.
I'm trying to optimize this code because this method is used in a high-throughput service, where this kind of allocation is prohibitive. Ideally, I would have rewritten the method as non-generic, but the API is widely used by various teams and a refactoring of such scale will take months. In the meantime I'm trying to mitigate the issue and find a way to improve the situation without changing the API contract. However I've been struggling on this for a while and have yet to find a solution.
Do you know a way, even ugly, to handle the int -> double and double -> int conversion without boxing, given the method contract? Note that I can't change the parameters but I could add a generic constraint (such as where TIn : IConvertible
, but this hasn't helped me much).
ChangeType
? You can use "switch/case" for all types you care and otherwise call boxed version. – Capernaum