Хабр Курсы для всех
РЕКЛАМА
 Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать! 
static void foo(ref T value)
{
//This is the ONLY way to treat value as int, without boxing/unboxing objects
if (value is int) __refvalue(__makeref(value), int) = 1;
else value = default(T); }
}
Allocation
In a classic semi-space collector allocation is done in a linear fashion by pointer bumping, i.e. simply incrementing the pointer that indicates the start of the current semi-space’s region that is still unused by the amount of memory that is required for the new object.
In a multi-threaded environment like Mono using a single pointer would introduce additional costs because we would have to do at least a compare-and-swap to increment it, potentially looping because it might fail due to contention. The standard solution to this problem is to give each thread a little piece of the nursery exclusively from which it can bump-allocate without contention. Synchronization is only needed when a thread has filled up its piece and needs a new one, which should be far less frequent. These pieces of nursery are called “thread local allocation buffers”, or “TLABs” for short.
Сразу сделаю ремарку: чаще всего проблемы производительности лежат на более высоком уровне, и прежде чем править весь лишний boxing, нужно привести код к такому состоянию, когда от этого будет толк.
    public static class BooleanBoxes
    {
        public static readonly object True = true;
        public static readonly object False = false;
        [Pure]
        public static object Box(bool value)
        {
            Contract.Ensures(Contract.Result<object>() != null);
            return value ? True : False;
        }
    }
Улучшаем производительность: boxing в .NET, которого можно избежать