Словарь .NET 4.0: Клавиша типа значения в штучной упаковке для тщетной проверки 'null'Вредит ли это производительности? - PullRequest
4 голосов
/ 03 декабря 2010

Например:

.method private hidebysig instance void Insert(!TKey key, !TValue 'value', bool add) cil managed
{
    .maxstack 3
    .locals init (
        [0] int32 num,
        [1] int32 num2,
        [2] int32 num3,
        [3] int32 num4)
    L_0000: ldarg.1 
    L_0001: box !TKey
    L_0006: brtrue.s L_000e
    L_0008: ldc.i4.5 
    L_0009: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)

Это из внутреннего Добавить метод словаряв .NET 4.0.Несмотря на то, что универсальные средства широко рекламируются как помогающие избежать упаковки типов значений, почему этот системный компонент выполняет эту неэффективную проверку каждой операции для ключа типа значения?Если я правильно понимаю, это не только ухудшает производительность, но и всегда возвращает true (тип в штучной упаковке никогда не будет пустой ссылкой)

edit: Резюме ответа Марка на этот конкретный вопрос: причина этогоимеет значение, что этот словарьРеализация предпочла запретить использование в качестве ключей экземпляров Nullable "null".Поскольку инструкция блока MSIL обеспечивает особый подход к типу значения Nullable , проверка не обязательно бесполезна для всех типов значений.

1 Ответ

1 голос
/ 03 декабря 2010

A Nullable<T> является struct / значением-типом и может быть null (в зависимости от вашего определения null; но, безусловно, оно может box до null). И не все TKey имеют тип значения (string является, пожалуй, наиболее распространенным TKey).

Здесь требуется, чтобы ключ не был нулевым; так что нужно проверить это.

На самом деле бокс не так плох, как думают люди; даже в штучной упаковке, он будет собран gen-0. Это может особый случай через дженерики (как EqualityComparer<T> делает - через несколько различных подклассов), но это кажется излишним.

JIT может также сможет удалить нулевую проверку. Я говорю может здесь, хотя это часто цитируется, я видел случаи, когда нулевая проверка была за пределами способности JIT удалить.

...