Skip to content

Instantly share code, notes, and snippets.

@SeriaWei
Created December 9, 2020 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SeriaWei/f63df2c91a3d24de2ec9a6a6ee95402d to your computer and use it in GitHub Desktop.
Save SeriaWei/f63df2c91a3d24de2ec9a6a6ee95402d to your computer and use it in GitHub Desktop.
C# Fast get property value
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
public class People
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
Directly();
Reflection();
Lambda();
Delegate();
Emit();
Console.ReadKey();
}
private static void Reflection()
{
People people = new People { Name = "Wayne" };
Type type = typeof(People);
PropertyInfo property = type.GetProperty("Name");
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object value = property.GetValue(people);
}
stopwatch.Stop();
Console.WriteLine("Reflection: {0}ms", stopwatch.ElapsedMilliseconds);
}
private static void Directly()
{
People people = new People { Name = "Wayne" };
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object value = people.Name;
}
stopwatch.Stop();
Console.WriteLine("Directly: {0}ms", stopwatch.ElapsedMilliseconds);
}
private static void Lambda()
{
People people = new People { Name = "Wayne" };
Type type = typeof(People);
var parameter = Expression.Parameter(type, "m");//参数m
PropertyInfo property = type.GetProperty("Name");
Expression expProperty = Expression.Property(parameter, property.Name);//取参数的属性m.Name
expProperty = Expression.Convert(expProperty, typeof(object));
var propertyDelegateExpression = Expression.Lambda(expProperty, parameter);//变成表达式 m => m.Name
var propertyDelegate = (Func<People, object>)propertyDelegateExpression.Compile();//编译成委托
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object value = propertyDelegate.Invoke(people);
}
stopwatch.Stop();
Console.WriteLine("Lambda:{0}ms", stopwatch.ElapsedMilliseconds);
}
private static void Delegate()
{
People people = new People { Name = "Wayne", Age = 1 };
Type type = typeof(People);
PropertyInfo property = type.GetProperty("Age");
Func<People, int> memberGet = (Func<People, int>)System.Delegate.CreateDelegate(typeof(Func<People, int>), property.GetGetMethod());
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object value = memberGet(people);
}
stopwatch.Stop();
Console.WriteLine("Delegate: {0}ms", stopwatch.ElapsedMilliseconds);
}
private static void Emit()
{
People people = new People { Name = "Wayne" };
Type type = typeof(People);
var property = type.GetProperty("Name");
DynamicMethod method = new DynamicMethod("GetPropertyValue", typeof(object), new Type[] { type }, true);
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, property.GetGetMethod());
if (property.PropertyType.IsValueType)
{
il.Emit(OpCodes.Box, property.PropertyType);
}
il.Emit(OpCodes.Ret);
Func<People, object> fun = method.CreateDelegate(typeof(Func<People, object>)) as Func<People, object>;
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
object value = fun.Invoke(people);
}
stopwatch.Stop();
Console.WriteLine("Emit:{0}ms", stopwatch.ElapsedMilliseconds);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment