开发者

.NET 4.0 Dictionary<TKey,TValue>: Value type key boxed for a futile 'null' check. Does this hurt performance?

开发者 https://www.devze.com 2023-01-28 11:59 出处:网络
For example: .method private hidebysig instance void Insert(!TKey key, !TValue \'value\', bool add) cil managed

For example:

.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)

This is from the internal Add method of Dictionary<int,Object> in .NET 4.0. Although generics are widely touted as helping to avoid boxing of value types, why is this system component doing this inefficient check on every operation for a value-type key? If I understand correctly, this not only hurts performance, but will always return true as well (a boxed value type will never be a null reference)

edit: Summary of Marc's answer for this specific question: the reason it matters is that this Dictionary<K,V> implementation has opted to disallow the use of "null" Nullable<T> instances as keys. Because the MSIL box instruction gives special treatment to the Nullable<T> value type, the check is not necessarily futile开发者_运维问答 for all value types.


A Nullable<T> is a struct / value-type, and can be null (depending on your definition of null; but certainly it can box to null). And not all TKey are value-type (string being perhaps the most common TKey).

There is a requirement here that the key isn't null; so it does need to verify that.

In reality, boxing isn't as bad as people think; even boxed, it will be gen-0 collected. It could special-case via generics (like EqualityComparer<T> does - via a few different sub-classes), but that seems overkill.

The JIT may also be able to remove the null-check. I say may here, as although this is often cited, I have seen cases where the null-check was beyond the JIT's ability to remove.

0

精彩评论

暂无评论...
验证码 换一张
取 消