After some benchmarks I noticed most of my methods I created which use reflection are very, very slow, especially when used in iterations. I found a post from C# Corner, which shows how to create delegates for the reflection methods, because the validation and security operations are only done once when creating the delegate instead of each loop.
The C# Corner post show a code example very similar to this:
public class Item
{
public int Value { get; set; }
}
List<Item> list = Enumerable.Repeat(new Item(), 10000000).ToList();
int i = 0;
foreach (var element in list)
{
i = element.Value;
element.Value = 3;
}
and then explains that using reflection instead has the drawback of drastically affecting performance:
PropertyInfo propInfo = typeof(Item).GetProperty("Value");
foreach (var element in list)
{
i = (int)propInfo.GetValue(element);
propInfo.SetValue(element, 3);
}
performance however can be improved by creating delegates:
Action<Item, int> setter = (Action<Item, int>)Delegate.CreateDelegate(
typeof(Action<Item, int>), null,
typeof(Item).GetProperty("Value").GetSetMethod());
Func<Item, int> getter = (Func<Item, int>)Delegate.CreateDelegate(
typeof(Func<Item, int>), null,
typeof(Item).GetProperty("Value").GetGetMethod());
foreach (var element in list)
{
i = (int)getter(element);
setter(element, 3);
}
Now some of my methods have generic type parameters and I haven't found out how to create delegates with generic parameters yet to get a similar performance boost. Example: Let's say I have following extension method and I want to move the reflection calls to delegates, how would I do this?
public static void SetValues<T>(this List<T> list)
{
var propInfos = typeof(T).GetProperties().AsSpan();
for(int i = 0; i < list.Count; i++)
{
var element = list[i];
for (int j = 0; j < propInfos.Length; j++)
{
var propInfo = propInfos[j];
if (propInfo.PropertyType == typeof(int) && (int)propInfo.GetValue(element) == default)
propInfo.SetValue(element, i);
}
}
}
I've found various solutions, that use an ILGenerator
to do this, as found in this MSDN Blog Post, but that has honestly been a little to abstract for my taste. I'd like to stay with C#, if possible.
Aucun commentaire:
Enregistrer un commentaire