I know premature optimization is the mother of all evil. However, I am defining a generic method that uses Reflection to retrieve its generic type's metadata, and would like to know whether calling typeof(T)
several times as in the following code snippet:
private static Dictionary<Type, PropertyInfo[]> elementProperties;
private static T MakeElement<T>(SqlDataReader reader) where T : class, new() {
PropertyInfo[] properties;
if (elementProperties.ContainsKey(typeof(T)))
properties = elementProperties[typeof(T)];
else
properties = elementProperties[typeof(T)] = typeof(T).GetProperties();
// more code...
}
... is less efficient than storing the type object into a variable as in the following code snippet:
private static Dictionary<Type, PropertyInfo[]> elementProperties;
private static T MakeElement<T>(SqlDataReader reader) where T : class, new() {
PropertyInfo[] properties;
Type type = typeof(T);
if (elementProperties.ContainsKey(type))
properties = elementProperties[type];
else
properties = elementProperties[type] = type.GetProperties();
// more code...
}
...?
If I understand compiler theory correctly (and I think I do), this question could be reduced to the following one:
When the JIT compiler instantiates a generic type, does it replace every instance of [whatever the MSIL representation of typeof(T)
is] with...
The most fundamental data type in the C language is the integer, whichis normally defined as the most efficient type for a given processor. The C language treats this type specially in that the language does notoperate on smaller types, at least conceptually speaking.
In that case, “C is the best solution, since it is dominant in both single objectives,” the researchers write. If you're trying to save time while using less memory, C, Pascal, and Go “are equivalent” — and the same is true if you're watching all three variables (time, energy use, and memory use).
Performance: C++ is widely used when higher level languages are not efficient. C++ code is much faster than C# code, which makes it a better solution for applications where performance is important.
Actually, the short answer is: Assembler is always faster or equal to the speed of C. The reason is that you can have assembly without C, but you can't have C without assembly (in the binary form, which we in the old days called "machine code").
A little intuition should tell you that declaring a single instance of a variable to hold the result of GetType(), which is then used throughout the rest method would be more efficient (and more readable to boot)
Here is the IL of the two methods:
MakeElement 1:
Icall System.Type.GetTypeFromHandle
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.ContainsKey
brfalse.s IL_002F
ldarg.0
ldfld elementProperties
ldtoken 01 00 00 1B
call System.Type.GetTypeFromHandle
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.get_Item
pop
br.s IL_0053
ldarg.0
ldfld elementProperties
ldtoken 01 00 00 1B
call System.Type.GetTypeFromHandle
ldtoken 01 00 00 1B
call System.Type.GetTypeFromHandle
call System.Type.GetProperties
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.set_Item
MakeElement 2:
call System.Type.GetTypeFromHandle
stloc.0
ldarg.0
ldfld elementProperties
ldloc.0
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.ContainsKey
brfalse.s IL_0028
ldarg.0
ldfld elementProperties
ldloc.0
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.get_Item
pop
br.s IL_003A
ldarg.0
ldfld elementProperties
ldloc.0
ldloc.0
callvirt System.Type.GetProperties
callvirt System.Collections.Generic.Dictionary<System.Type,System.Reflection.PropertyInfo[]>.set_Item
You save 1 or 2 calls to System.Type.GetTypeFromHandle by declaring it in the local variable. I'm not certain that the JIT'ing process won't compile those out, but I would personally put more faith in the compiler to optimize the IL for things like over the JIT'er, but that's just me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With