I'm trying to investigate whether dictionaries with enum keys still generate garbage in newer versions of .Net (say >= 4)
See Shawn Hargreaves blog post here for details on why I'm even fretting about this... (http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage-collector-nirvana.aspx) Very specific I know but garbage on the xbox is / can be a very really problem.
I created a little .Net v4 console application comparing the IL generated for Dictionary and Dicationary and noticed a 'box' opcode in both sets of code which really confused me.
.method private hidebysig
instance int32 FindEntry (
!TKey key
) cil managed
{
// Method begins at RVA 0x61030
// Code size 138 (0x8a)
.maxstack 3
.locals init (
[0] int32,
[1] int32
)
IL_0000: ldarg.1
IL_0001: box !TKey <----Hmmmm!
IL_0006: brtrue.s IL_000e
IL_0008: ldc.i4.5
IL_0009: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
IL_000e: ldarg.0
IL_000f: ldfld int32[] class System.Collections.Generic.Dictionary`2<!TKey, !TValue>::buckets
IL_0014: brfalse.s IL_0088
https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.box%28v=vs.110%29.aspx
Convert a value type (of the type specified in valTypeToken) to a true object reference.
Is the box here not a heap allocation? If not, then how can I tell when there's heap allocations that might cause the Xbox to struggle?(from looking at the IL) Does it depend on some other context? Would a memory profiler (CLR Profiler for example) be the only way to tell for sure?
Yes it is a box, but no it shouldn't matter in this case - at least, not for regular .NET; this is a != null
check; the JIT knows how to recognise these for value-types, and can remove that check from the machine code.
Allegedly.
To tell for sure, you'd need to look at the post-JIT machine code, not the IL.
It will also matter which JIT you are using, which makes it harder.
Worst case: you could use the CoreCLR code to roll your own value-type dictionary.