I have read several posts on SO about writing and compiling dynamic C# code. For example, this post. I understand it can be done several ways.
However, calling the code invoker is slow. I did a simple benchmark, and it's some 500 X slower than calling a native method.
What I want to be able to do is the equivalent of loading a DLL and calling one of its methods directly ("natively"), which will give the speed benefits I want.
What is the easiest way to go about this? Compile the dynamic code to a dll and then load it? Can it be done in memory?
EDIT
I don't care about compilation time. Only execution.
EDIT 2, 3
Here is the benchmark code I wrote:
public static int Execute(int i) { return i * 2; }
private void button30_Click(object sender, EventArgs e)
{
CSharpCodeProvider foo = new CSharpCodeProvider();
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true,
CompilerOptions = #"/optimize",
},
#"public class FooClass { public static int Execute(int i) { return i * 2; }}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var method = type.GetMethod("Execute");
int i = 0, t1 = Environment.TickCount, t2;
//var input = new object[] { 2 };
//for (int j = 0; j < 10000000; j++)
//{
// input[0] = j;
// var output = method.Invoke(obj, input);
// i = (int)output;
//}
//t2 = Environment.TickCount;
//MessageBox.Show((t2 - t1).ToString() + Environment.NewLine + i.ToString());
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = Execute(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Native: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
var func = (Func<int, int>) Delegate.CreateDelegate(typeof (Func<int, int>), method);
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = func(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Dynamic delegate: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
Func<int, int> funcL = Execute;
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = funcL(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Delegate: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
}
Yes, if you invoke via a MethodInfo or a non-specific Delegate, then it will indeed be slow. The trick is: don't do that. Various approaches:
for individual methods, go via a basic but typed delegate, such as Action, or as a generic catch-all, Func<object[], object> - and use Delegate.CreateDelegate to create a typed delegate:
Action doSomething = (Action)Delegate.CreateDelegate(typeof(Action), method);
another variant of this is to use the Expression API (which has a .Compile() method), or DynamicMethod (which has CreateDelegate()). The key thing: you must get a typed delegate and invoke using typed invoke (not .DynamicInvoke).
for more complex cases where you are generating whole types, consider implementing an interface you know about, i.e.
IFoo foo = (IFoo)Activator.CreateInstance(...);
again; after the initial cast (which is very cheap) you can just use static code:
foo.Bar();
Do not use someDelegate.DynamicInvoke(...) or someMethod.Invoke(...) if you are after any kind of performance.
Besides Marc's advice you could improve speed by specifying the "optimize" compiler option:
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true,
CompilerOptions = "/optimize"
},
Thought it was worth showing how all potential options looked and their performance characteristics. Given the following helper classes and functions:
public void Test(Func<int> func)
{
var watch = new Stopwatch();
watch.Start();
for (var i = 0; i <= 1000000; i++)
{
var test = func();
}
Console.WriteLine(watch.ElapsedMilliseconds);
}
public class FooClass { public int Execute() { return 1;}}
Set up and execution:
using (Microsoft.CSharp.CSharpCodeProvider foo =
new Microsoft.CSharp.CSharpCodeProvider())
{
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
"public class FooClass { public int Execute() { return 1;}}"
);
var real = new FooClass();
Test(() => real.Execute()); // benchmark, direct call
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var method = type.GetMethod("Execute");
var input = new object[] { };
Test(() => (int)method.Invoke(obj, input)); // reflection invoke
dynamic dyn = Activator.CreateInstance(type);
Test(() => dyn.Execute()); // dynamic object invoke
var action = (Func<int>)Delegate.CreateDelegate(typeof(Func<int>), null, method);
Test(() => action()); // delegate
}
The results are:
8 // direct
771 // reflection invoke
41 // dynamic object invoke
7 // delegate
So in those cases where you can't use delegates (if you don't know enough?), you can try dynamic.
Related
Thread[] threads = new Thread[12];
int temp;
for (int i = 0; i < threads.Length - 1; i++)
{
temp = i;
threads[temp] = new Thread(new ThreadStart(()=> test(test1[temp],"start", temp)));
threads[temp].Start();
//threads[temp].Join();
}
for(int i=0; i<threads.Length-1; i++)
{
threads[i].Join();
}
//Need to capture the response returned from method executed"test1" in thread.
You could use a Task<T> (if you're on .NET 4+), which has a return value. You could also use events to get notified when the thread is done with doing whatever it does and get the returned value that way.
I would use Microsoft's Reactive Framework for this. NugGet "Rx-Main".
var query =
Observable
.Range(0, 12)
.SelectMany(n => Observable
.Start(() => new
{
n,
r = test(test1[n], "start", n)
}))
.ToArray()
.Select(xs => xs
.OrderBy(x => x.n)
.Select(x => x.r)
.ToArray());
query.Subscribe(rs =>
{
/* do something with the results */
});
You could start the thread using another ctor overload where you can start the thread and pass an object to that thread. The thread would then save the result in a field of that object. The main thread could after the call to Join retrieve the results from all those objects. You could have an array of 12 objects each of them passed to one thread. Or you could have an array of 12 classes, each class encapsulating one thread and the corresponding object that wraps the result:
public class ThreadResult
{
public int Result {get; set;}
}
However, today you have better choices than raw threads. Take a look at TPL (Task Parallel Library) and async / await in C#.
You can also use a shared state, in this case you have to lock every access to the shared objects inside the thread method:
Thread[] threads = new Thread[12];
int temp;
string msg = "";
List<string> results = new List<string>();
for (int i = 0; i < threads.Length; i++)
{
temp = i;
threads[temp] = new Thread(() =>
{
lock (results)
{
lock (msg)
{
msg = "Hello from Thread " + Thread.CurrentThread.ManagedThreadId;
results.Add(msg);
}
}
});
threads[temp].Start();
}
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
I'm testing the performance of some similar method calls that I'm wrapping in some timing and logging statements. I'm passing these methods in via an Action delegate parameter.
Is there any way to print details about the call?
For example:
var httpResult = TestService(() => serviceHttp.Search(criteria));
var tcpResult = TestService(() => serviceTcp.Search(criteria));
var localResult = TestService(() => servicelocal.Search(criteria));
...
private static double TestService(Action serviceOperation)
{
const int iterations = 15;
...
for (var i = 0; i < iterations; i++)
{
var watch = Stopwatch.StartNew();
...
Console.WriteLine(string.Format("{0} ElapsedMilliseconds={1}", ????, watch.ElapsedMilliseconds));
// Ideally this would print something like "serviceTcp.DoStuff(...) ElapsedMilliseconds=313"
}
...
}
Change your testing method declaration to
private static double TestService(Expression<Action> expression)
Call Compile method of expression object to get a method for testing:
var serviceOperation = expression.Compile();
Expression object can provide a lot of information about method call, you can start with something like this:
private static string GetMethodCallDescription(Expression<Action> expression)
{
var mce = (MethodCallExpression)expression.Body;
var method = mce.Method;
var sb = new StringBuilder();
sb.Append(method.DeclaringType.Name);
sb.Append(".");
sb.Append(method.Name);
sb.Append("(");
bool firstarg = true;
foreach(var arg in mce.Arguments)
{
if(!firstarg)
{
sb.Append(", ");
}
else
{
firstarg = false;
}
sb.Append(arg.ToString());
}
sb.Append(")");
return sb.ToString();
}
You could do it without using expression trees; just change the signature of TestService to take the action and the parameter separately, and use the Delegate.Target and Delegate.Method properties to get the type and method:
var httpResult = TestService(serviceHttp.Search, criteria);
var tcpResult = TestService(serviceTcp.Search, criteria);
var localResult = TestService(servicelocal.Search, criteria);
...
private static double TestService<T>(Action<T> serviceOperation, T parameter)
{
const int iterations = 15;
...
for (var i = 0; i < iterations; i++)
{
var watch = Stopwatch.StartNew();
...
string typeName = serviceOperation.Method.IsStatic
? serviceOperation.Method.DeclaringType.Name
: serviceOperation.Target.GetType().Name;
string methodName = serviceOperation.Method.Name;
Console.WriteLine(string.Format("{0}.{1} ElapsedMilliseconds={2}", typeName, methodName, watch.ElapsedMilliseconds));
// Ideally this would print something like "serviceTcp.DoStuff(...) ElapsedMilliseconds=313"
}
...
}
are there any differences in the references that are produced in code generated for anonymous methods by a .NET 2.0 or 4.0 compiler and code generated for an equivalent lambda by a .NET 4.0 compiler? and in particular for the this pointer: I know both anonymous methods and lambdas are a C# compiler feature and the compiler actually generates a nested class with a delegate and all the references required for outer variables, but this article on the implementation of anonymous methods states a reference is kept to the pointer and I cannot find any source describing anything similar for lambdas.. or am I not finding anything because the implementation for compiling anonymous methods maps 1 on 1 to that of lambdas?
here's a bit of code to demonstrate anonymous methods and lambdas:
class AnonymousMethodMethodScope
{
private Func<bool> d;
public Func<int, bool> d2;
int j = 0;
public void Test(int i)
{
d = new Func<bool>(delegate { j = 10; return j > i; });
// what references does this anonymous method keep?
d2 = new Func<int, bool>(delegate(int x) { return x == j; });
Console.WriteLine("j = " + j + " result = " + d());
}
}
class LambdaMethodScope
{
private Func<bool> d;
public Func<int, bool> d2;
public void Test(int i)
{
int j = 0;
d = () => { j = 10; return j > i; };
// what references does this lambda keep?
d2 = x => x == j;
Console.WriteLine("j = " + j + " result = " + d());
}
}
Yes, lambda expressions will do (and have to do) the same thing as anonymous methods when it comes to capturing variables. (I'm assuming you're talking about lambda expressions which are converted into delegates; if they're converted into expression trees they may be a bit different - I'm not sure.)
The docs for both DynamicInvoke and DynamicInvokeImpl say:
Dynamically invokes (late-bound) the
method represented by the current
delegate.
I notice that DynamicInvoke and DynamicInvokeImpl take an array of objects instead of a specific list of arguments (which is the late-bound part I'm guessing). But is that the only difference? And what is the difference between DynamicInvoke and DynamicInvokeImpl.
The main difference between calling it directly (which is short-hand for Invoke(...)) and using DynamicInvoke is performance; a factor of more than *700 by my measure (below).
With the direct/Invoke approach, the arguments are already pre-validated via the method signature, and the code already exists to pass those into the method directly (I would say "as IL", but I seem to recall that the runtime provides this directly, without any IL). With DynamicInvoke it needs to check them from the array via reflection (i.e. are they all appropriate for this call; do they need unboxing, etc); this is slow (if you are using it in a tight loop), and should be avoided where possible.
Example; results first (I increased the LOOP count from the previous edit, to give a sensible comparison):
Direct: 53ms
Invoke: 53ms
DynamicInvoke (re-use args): 37728ms
DynamicInvoke (per-cal args): 39911ms
With code:
static void DoesNothing(int a, string b, float? c) { }
static void Main() {
Action<int, string, float?> method = DoesNothing;
int a = 23;
string b = "abc";
float? c = null;
const int LOOP = 5000000;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++) {
method(a, b, c);
}
watch.Stop();
Console.WriteLine("Direct: " + watch.ElapsedMilliseconds + "ms");
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++) {
method.Invoke(a, b, c);
}
watch.Stop();
Console.WriteLine("Invoke: " + watch.ElapsedMilliseconds + "ms");
object[] args = new object[] { a, b, c };
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++) {
method.DynamicInvoke(args);
}
watch.Stop();
Console.WriteLine("DynamicInvoke (re-use args): "
+ watch.ElapsedMilliseconds + "ms");
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++) {
method.DynamicInvoke(a,b,c);
}
watch.Stop();
Console.WriteLine("DynamicInvoke (per-cal args): "
+ watch.ElapsedMilliseconds + "ms");
}
Coincidentally I have found another difference.
If Invoke throws an exception it can be caught by the expected exception type.
However DynamicInvoke throws a TargetInvokationException. Here is a small demo:
using System;
using System.Collections.Generic;
namespace DynamicInvokeVsInvoke
{
public class StrategiesProvider
{
private readonly Dictionary<StrategyTypes, Action> strategies;
public StrategiesProvider()
{
strategies = new Dictionary<StrategyTypes, Action>
{
{StrategyTypes.NoWay, () => { throw new NotSupportedException(); }}
// more strategies...
};
}
public void CallStrategyWithDynamicInvoke(StrategyTypes strategyType)
{
strategies[strategyType].DynamicInvoke();
}
public void CallStrategyWithInvoke(StrategyTypes strategyType)
{
strategies[strategyType].Invoke();
}
}
public enum StrategyTypes
{
NoWay = 0,
ThisWay,
ThatWay
}
}
While the second test goes green, the first one faces a TargetInvokationException.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SharpTestsEx;
namespace DynamicInvokeVsInvoke.Tests
{
[TestClass]
public class DynamicInvokeVsInvokeTests
{
[TestMethod]
public void Call_strategy_with_dynamic_invoke_can_be_catched()
{
bool catched = false;
try
{
new StrategiesProvider().CallStrategyWithDynamicInvoke(StrategyTypes.NoWay);
}
catch(NotSupportedException exc)
{
/* Fails because the NotSupportedException is wrapped
* inside a TargetInvokationException! */
catched = true;
}
catched.Should().Be(true);
}
[TestMethod]
public void Call_strategy_with_invoke_can_be_catched()
{
bool catched = false;
try
{
new StrategiesProvider().CallStrategyWithInvoke(StrategyTypes.NoWay);
}
catch(NotSupportedException exc)
{
catched = true;
}
catched.Should().Be(true);
}
}
}
Really there is no functional difference between the two. if you pull up the implementation in reflector, you'll notice that DynamicInvoke just calls DynamicInvokeImpl with the same set of arguments. No extra validation is done and it's a non-virtual method so there is no chance for it's behavior to be changed by a derived class. DynamicInvokeImpl is a virtual method where all of the actual work is done.
What is the best way to find something in a list? I know LINQ has some nice tricks, but let's also get suggestions for C# 2.0. Lets get the best refactorings for this common code pattern.
Currently I use code like this:
// mObjList is a List<MyObject>
MyObject match = null;
foreach (MyObject mo in mObjList)
{
if (Criteria(mo))
{
match = mo;
break;
}
}
or
// mObjList is a List<MyObject>
bool foundIt = false;
foreach (MyObject mo in mObjList)
{
if (Criteria(mo))
{
foundIt = true;
break;
}
}
# Konrad: So how do you use it? Let's say I want to match mo.ID to magicNumber.
In C# 2.0 you'd write:
result = mObjList.Find(delegate(int x) { return x.ID == magicNumber; });
3.0 knows lambdas:
result = mObjList.Find(x => x.ID == magicNumber);
Using a Lambda expression:
List<MyObject> list = new List<MyObject>();
// populate the list with objects..
return list.Find(o => o.Id == myCriteria);
Put the code in a method and you save a temporary and a break (and you recycle code, as a bonus):
T Find<T>(IEnumerable<T> items, Predicate<T> p) {
foreach (T item in items)
if (p(item))
return item;
return null;
}
… but of course this method already exists anyway for Lists, even in .NET 2.0.
Evidently the performance hit of anonymous delegates is pretty significant.
Test code:
static void Main(string[] args)
{
for (int kk = 0; kk < 10; kk++)
{
List<int> tmp = new List<int>();
for (int i = 0; i < 100; i++)
tmp.Add(i);
int sum = 0;
long start = DateTime.Now.Ticks;
for (int i = 0; i < 1000000; i++)
sum += tmp.Find(delegate(int x) { return x == 3; });
Console.WriteLine("Anonymous delegates: " + (DateTime.Now.Ticks - start));
start = DateTime.Now.Ticks;
sum = 0;
for (int i = 0; i < 1000000; i++)
{
int match = 0;
for (int j = 0; j < tmp.Count; j++)
{
if (tmp[j] == 3)
{
match = tmp[j];
break;
}
}
sum += match;
}
Console.WriteLine("Classic C++ Style: " + (DateTime.Now.Ticks - start));
Console.WriteLine();
}
}
Results:
Anonymous delegates: 710000
Classic C++ Style: 340000
Anonymous delegates: 630000
Classic C++ Style: 320000
Anonymous delegates: 630000
Classic C++ Style: 330000
Anonymous delegates: 630000
Classic C++ Style: 320000
Anonymous delegates: 610000
Classic C++ Style: 340000
Anonymous delegates: 630000
Classic C++ Style: 330000
Anonymous delegates: 650000
Classic C++ Style: 330000
Anonymous delegates: 620000
Classic C++ Style: 330000
Anonymous delegates: 620000
Classic C++ Style: 340000
Anonymous delegates: 620000
Classic C++ Style: 400000
In every case, using anonymous delegates is about 100% slower than the other way.