How to use RuntimeHelpers.IsReferenceOrContainsReferences to micro-optimize collections
RuntimeHelpers.IsReferenceOrContainsReferences<T>()
is a method that indicates if T
is a reference type or contains a reference type. One use case for this method is to micro-optimize collections when removing items. Indeed, if T
is a reference type, you need to remove the reference to the item to allow the GC to collect it. If T
is a value type, you don't need to do that so you can avoid memory access. This is a very small optimization, but it can be useful in some cases. Note that the JIT will replace the statement with a constant and remove branches that are always false.
Here's an example of a custom list that uses this method:
C#
class CustomList<T>
{
private readonly T[] _items;
private int _count;
public CustomList(int capacity)
=> _items = new T[capacity];
public void Push(T item)
{
if (_count == _items.Length)
throw new InvalidOperationException("The list is full.");
_items[_count] = item;
_count++;
}
public T Pop()
{
if (_count == 0)
throw new InvalidOperationException("The list is empty.");
var value = _items[_count - 1];
// If T is a reference type or contains a reference type, you need to remove
// the reference to the item to allow the GC to collect it.
// For instance, CustomList<string> will need to do that, but CustomList<int> won't.
// Note: The JIT will remove the if statement if the condition is false, so there is no performance impact.
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
_items[count - 1] = default;
}
_count--;
return value;
}
}
Do you have a question or a suggestion about this post? Contact me!
Enjoy this blog?💖 Sponsor on GitHub