Created
December 9, 2020 13:55
-
-
Save SeriaWei/f63df2c91a3d24de2ec9a6a6ee95402d to your computer and use it in GitHub Desktop.
C# Fast get property value
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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