tgoop.com/csharp_gepard/138
Last Update:
ByReferenceTypeComparer #скорость
Если хорошенько подумать, то ByReferenceComparer
из предыдущего поста может хорошо помочь при сравнении всего, что существует в приложении от начала и до конца его жизни. Например, тип Type
, который часто используется для логеров, сериализаторов и ветвления логики, в зависимости от типа входящего параметра.
Напомню, что типы хранятся в приложении постоянно (скорее всего, исключая сценарии загрузки и выгрузки Assembly
) и представляются одним и только одним инстансом. Это очень хорошо ложится на сценарий, аналогичного строке, которая хранится в таблице интернирования.
Таким образом, если у нас есть Dictionary<Type, ???>
, то мы можем ускорить его работу на 20-30%, просто передав ему сравниватель, который будет проверять равенство по ссылке, а hash брать из заголовка типа.
private sealed class ByReferenceComparer<T> : IEqualityComparer<T>
where T : class
{
public static readonly IEqualityComparer<T> Instance = new ByReferenceComparer<T>();
private ByReferenceComparer()
{
}
public bool Equals(T? x, T? y) => ReferenceEquals(x, y);
public int GetHashCode(T obj) => RuntimeHelpers.GetHashCode(obj);
}
Бенчмарк в комментариях.
Запуск на MacBook.
P.S.: Если кого-то волнует, работает ли подобный подход в сценарии, когда мы создаём тип "налету" (а-ля
typeof(List<>).MakeGenericType(typeof(int))
), то да, так тоже работает.P.P.S.: Остаётся открытым вопрос, почему так не делают в .net по-умолчанию. Скорее всего, есть какой-то нюанс, который я упускаю (напр., тут). Возможно, мы вместе найдём на него ответ. Предположительный ответ.
BY C# Heppard

Share with your friend now:
tgoop.com/csharp_gepard/138