-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
135 lines (109 loc) · 4.25 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using BuildingBlocks;
using CsvHelper;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace SpeedTest
{
class Program
{
const int ITERATIONS = 1000000;
const int RUNS = 10;
static void Main(string[] args)
{
Console.Write("Running... ");
var times = Enumerable.Range(1, RUNS)
.Select(run => new
{
Run = run,
Native = Time(RunNative),
Dynamic = Time(RunDynamic),
Reflection = Time(RunReflection),
ExpressionTree = Time(RunExpressionTree),
RuntimeAction = Time(RunRuntimeAction),
CreateDelegate = Time(RunCreateDelegate)
})
.ToArray();
using (var csv = new CsvWriter(File.CreateText(String.Format("runtimes-{0:yyyyMMddHHmmss}.csv", DateTime.Now))))
{
csv.WriteRecords(times);
}
Console.WriteLine("Done");
}
static readonly Lazy<Action<TestTarget, string>> s_native = new Lazy<Action<TestTarget, string>>(() => (inst, value) => inst.DoSomething(value));
static void RunNative()
{
var inst = new TestTarget();
for (int i = 0; i < ITERATIONS; i++)
{
s_native.Value(inst, string.Empty);
}
}
static readonly Lazy<Action<dynamic, string>> s_dynamic = new Lazy<Action<dynamic, string>>(() => (inst, value) => inst.DoSomething(value));
static void RunDynamic()
{
var inst = new TestTarget();
for (int i = 0; i < ITERATIONS; i++)
{
s_dynamic.Value(inst, string.Empty);
}
}
static readonly Lazy<MethodInfo> s_methodInfo = new Lazy<MethodInfo>(() => typeof(TestTarget).GetMethod("DoSomething"));
static void RunReflection()
{
var inst = new TestTarget();
for (int i = 0; i < ITERATIONS; i++)
{
s_methodInfo.Value.Invoke(inst, new object[] { string.Empty });
}
}
static readonly Lazy<Action<TestTarget, string>> s_expressionTree = new Lazy<Action<TestTarget, string>>(BuildExpressionTreeAction);
static void RunExpressionTree()
{
var inst = new TestTarget();
for (int i = 0; i < ITERATIONS; i++)
{
s_expressionTree.Value(inst, string.Empty);
}
}
static Action<TestTarget, string> BuildExpressionTreeAction()
{
var method = typeof(TestTarget).GetMethod("DoSomething");
var pTarget = Expression.Parameter(typeof(TestTarget), "target");
var pValue = Expression.Parameter(typeof(string), "value");
var body = Expression.Call(pTarget, method, pValue);
var lambda = Expression.Lambda<Action<TestTarget, string>>(body, pTarget, pValue);
return lambda.Compile();
}
static readonly Lazy<RuntimeAction<TestTarget, string>> s_runtimeAction = new Lazy<RuntimeAction<TestTarget, string>>(() => new RuntimeAction<TestTarget, string>(typeof(TestTarget).GetMethod("DoSomething")));
static void RunRuntimeAction()
{
var inst = new TestTarget();
for (int i = 0; i < ITERATIONS; i++)
{
s_runtimeAction.Value.Invoke(inst, string.Empty);
}
}
static readonly Lazy<Action<string>> s_createDelegate = new Lazy<Action<string>>(() => (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), new TestTarget(), typeof(TestTarget).GetMethod("DoSomething")));
static void RunCreateDelegate()
{
for (int i = 0; i < ITERATIONS; i++)
{
s_createDelegate.Value(string.Empty);
}
}
static double Time(Action action)
{
var watch = Stopwatch.StartNew();
action();
watch.Stop();
return watch.ElapsedMilliseconds;
}
}
}