Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class MyClass
- {
- public string String { get; set; }
- }
- class Program
- {
- private const int Iterations = 10000;
- private static TimeSpan BaseLine;
- static void Main(string[] args)
- {
- var instance = new MyClass { String = "foo" };
- Benchmark(() => RawAccess(instance), true);
- Benchmark(() => ReflectionNoCache(instance));
- Benchmark(() => ReflectionWithCache(instance));
- Benchmark(() => ExpressionNoCache(instance));
- Benchmark(() => ExpressionWithCache(instance));
- Console.ReadKey(true);
- }
- private static void RawAccess(MyClass obj)
- {
- _ = obj.String;
- }
- private static void ReflectionNoCache(MyClass obj)
- {
- obj.GetType().GetProperty(nameof(MyClass.String)).GetValue(obj);
- }
- private static PropertyInfo Prop;
- private static void ReflectionWithCache(MyClass obj)
- {
- if (Prop == null)
- Prop = obj.GetType().GetProperty(nameof(MyClass.String));
- Prop.GetValue(obj);
- }
- private static void ExpressionNoCache(MyClass obj)
- {
- var expr = BuildExpression<MyClass, string>(nameof(MyClass.String));
- var getter = expr.Compile();
- getter(obj);
- }
- private static Func<MyClass, string> GetterFunc;
- private static void ExpressionWithCache(MyClass obj)
- {
- if (GetterFunc == null)
- GetterFunc = BuildExpression<MyClass, string>(nameof(MyClass.String)).Compile();
- GetterFunc(obj);
- }
- private static Expression<Func<TClass, TProp>> BuildExpression<TClass, TProp>(string propName)
- {
- //You could also use an expression to get the property here like in the Benchmark method
- var prop = typeof(TClass).GetProperty(propName);
- var instanceParam = Expression.Parameter(typeof(TClass), "instance");
- return Expression.Lambda<Func<TClass, TProp>>(Expression.Property(instanceParam, prop), instanceParam);
- }
- public static TimeSpan Benchmark(Expression<Action> expr, bool isBaseline = false)
- {
- string name = ((MethodCallExpression)expr.Body).Method.Name; //Another use for expressions ;)
- Console.Write($"{name,20}: ");
- var action = expr.Compile();
- action(); //Run once first to build caches, otherwise the cached methods are at a big disadvantage
- var sw = Stopwatch.StartNew();
- for (int i = 0; i < Iterations; i++)
- {
- action();
- }
- sw.Stop();
- if (isBaseline)
- BaseLine = sw.Elapsed;
- Console.WriteLine($"{sw.Elapsed} b*{sw.Elapsed / BaseLine:0.0} ({sw.Elapsed.TotalMilliseconds / Iterations}ms per iteration)");
- return sw.Elapsed;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement