Last active
September 8, 2015 15:44
-
-
Save khalidsalomao/facf4e1f5d61523dbd14 to your computer and use it in GitHub Desktop.
LinqPad - C# Benchmark - Reflection vs Lambda Expression
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
<Query Kind="Program" /> | |
void Main() | |
{ | |
// initialization | |
if (System.Diagnostics.Debugger.IsAttached) | |
System.Diagnostics.Debugger.Break (); | |
Console.WriteLine ("========================================="); | |
Console.WriteLine ("Warm up phase ..."); | |
// first call to discard JIT timming | |
Execute1 (1); | |
Execute2 (1); | |
// execute test | |
GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced); | |
GC.WaitForPendingFinalizers (); | |
Console.WriteLine ("========================================="); | |
Execute1 (1000000); | |
GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced); | |
GC.WaitForPendingFinalizers (); | |
Console.WriteLine ("========================================="); | |
Execute2 (1000000); | |
GC.Collect (GC.MaxGeneration, GCCollectionMode.Forced); | |
GC.WaitForPendingFinalizers (); | |
} | |
static void Execute1 (int count) | |
{ | |
var testObject = new sample (); | |
var prop = GetTypeProperties (testObject.GetType ()).First (); | |
long s = 0; | |
// start timer | |
var t = Stopwatch.StartNew (); | |
// code | |
for (int i = 0; i < count; i++) | |
{ | |
prop.SetValue (testObject, "123456789", null); | |
s += (prop.GetValue (testObject, null) as string).Length; | |
} | |
// stop timer | |
t.Stop (); | |
Console.WriteLine ("Execute1 time = " + t.ElapsedMilliseconds + " ms"); | |
Console.WriteLine(s); | |
} | |
static void Execute2 (int count) | |
{ | |
var testObject = new sample (); | |
var prop = GetTypeProperties (testObject.GetType ()).First (); | |
var getMethod = CreatePropertyGetter<sample> (prop); | |
var setMethod = CreatePropertySetter<sample> (prop); | |
long s = 0; | |
// start timer | |
var t = Stopwatch.StartNew (); | |
// code | |
for (int i = 0; i < count; i++) | |
{ | |
setMethod (testObject, "123456789"); | |
s += (getMethod (testObject) as string).Length; | |
} | |
// stop timer | |
t.Stop (); | |
Console.WriteLine ("Execute2 time = " + t.ElapsedMilliseconds + " ms"); | |
Console.WriteLine(s); | |
} | |
class sample | |
{ | |
public string id { get;set;} | |
} | |
/// <summary> | |
/// Gets the type properties. | |
/// </summary> | |
/// <param name="currentType">Type of the current.</param> | |
/// <param name="recursiveBaseType">Type of the recursive base.</param> | |
/// <param name="publicOnly">The public only.</param> | |
/// <param name="selectReadWrite">The select only properties with read and write capabilities.</param> | |
/// <returns></returns> | |
private static IEnumerable<PropertyInfo> GetTypeProperties (Type currentType, bool recursiveBaseType = true, bool publicOnly = true) | |
{ | |
return currentType.GetProperties ( | |
(publicOnly ? BindingFlags.Public : (BindingFlags.Public | BindingFlags.NonPublic)) // Get public only or all | |
| (recursiveBaseType ? (BindingFlags.Instance | BindingFlags.FlattenHierarchy) : BindingFlags.Instance)); | |
} | |
/// <summary> | |
/// Creates a property getter method with Lambda Expressions. | |
/// </summary> | |
/// <param name="propertyInfo">The property info.</param> | |
private static Func<T, object> CreatePropertyGetter<T>(System.Reflection.PropertyInfo propertyInfo, string propertyName = null) | |
{ | |
if (String.IsNullOrEmpty(propertyName)) | |
propertyName = propertyInfo.Name; | |
var source = Expression.Parameter(typeof(T)); | |
return Expression.Lambda<Func<T, object>>(Expression.Convert(Expression.Property(source, propertyName), typeof (object)), source).Compile(); | |
} | |
/// <summary> | |
/// Creates a property setter method with Lambda Expressions. | |
/// </summary> | |
/// <param name="propertyInfo">The property info.</param> | |
private static Action<T, object> CreatePropertySetter<T>(System.Reflection.PropertyInfo propertyInfo, string propertyName = null) | |
{ | |
if (String.IsNullOrEmpty(propertyName)) | |
propertyName = propertyInfo.Name; | |
var propType = propertyInfo.PropertyType; | |
var sourceType = Expression.Parameter(typeof(T)); | |
var argument = Expression.Parameter(typeof(object), propertyName); | |
var propExp = Expression.Property(sourceType, propertyName); | |
var castToObject = Expression.Convert(argument, propType); | |
return Expression.Lambda<Action<T, object>>(Expression.Assign(propExp, castToObject), sourceType, argument).Compile(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment