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.)
Related
I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails?
Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array.
public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
var randomNumb1 = new Random();
for (int i = 0; i < inputArray.Length - 1; i++)
{
Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
}
}
I had to look twice at this, but here's the issue:
Because inputArray is an 'array of type T'
then even though i is an int the expression
inputArray[i]
returns a type T not a type int.
And so, conversely, a type T must be assigned to it.
A generic method like this might achieve your goal:
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
// Where T has a CTor that takes an int as an argument
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
(Thanks to this SO post for refreshing my memory about instantiating T with arguments.)
You could also use Enumerable.Range() to get the same result without writing a method at all:
// Generically, for any 'SomeClass' with a CTor(int value)
SomeClass[] arrayOfT =
Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501)))
.ToArray();
(Slightly Modified with help from this SO post) - see the answer using Enumerable.Range().
Here is a test runner:
class Program
{
static Random Random { get; } = new Random();
const int LENGTH = 10;
static void Main(string[] args)
{
Console.WriteLine();
Console.WriteLine("With a generic you could do this...");
SomeClass[] arrayOfT;
arrayOfT = new SomeClass[LENGTH];
fillGenericArray<SomeClass>(arrayOfT);
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field=>field.Value)));
Console.WriteLine();
Console.WriteLine("But perhaps it's redundant, because Enumerable is already Generic!");
arrayOfT = Enumerable.Range(1, LENGTH).Select(i => new SomeClass(Random.Next(1, 501))).ToArray();
Console.WriteLine(string.Join(Environment.NewLine, arrayOfT.Select(field => field.Value)));
// Pause
Console.WriteLine(Environment.NewLine + "Any key to exit");
Console.ReadKey();
}
public static void fillGenericArray<T>(T[] inputArray)
{
for (int i = 0; i < inputArray.Length; i++)
{
inputArray[i] = (T)Activator.CreateInstance(typeof(T), Random.Next(1, 501));
}
}
class SomeClass
{
public SomeClass(int value)
{
Value = value;
}
public int Value { get; set; }
}
}
Clone or Download this example from GitHub.
There is no reason to use generics. Just replace T with int and you will have function that does what you want (based on your question and comment below it).
EDIT: From your comment it seems you misunderstand the purpose of generics. The non-generic function WILL work for all lengths of the array.
And to answer why the change to generics fails. You are trying to assign int to generic type T which can be anything and compiler will not allow such a cast.
I believe Microsoft claims that generics is faster than using plain polymorphism when dealing with reference types. However the following simple test (64bit VS2012) would indicate otherwise. I typically get 10% faster stopwatch times using polymorphism. Am I misinterpreting the results?
public interface Base { Int64 Size { get; } }
public class Derived : Base { public Int64 Size { get { return 10; } } }
public class GenericProcessor<TT> where TT : Base
{
private Int64 sum;
public GenericProcessor(){ sum = 0; }
public void process(TT o){ sum += o.Size; }
public Int64 Sum { get { return sum; } }
}
public class PolymorphicProcessor
{
private Int64 sum;
public PolymorphicProcessor(){ sum = 0; }
public void process(Base o){ sum += o.Size; }
public Int64 Sum { get { return sum; } }
}
static void Main(string[] args)
{
var generic_processor = new GenericProcessor<Derived>();
var polymorphic_processor = new PolymorphicProcessor();
Stopwatch sw = new Stopwatch();
int N = 100000000;
var derived = new Derived();
sw.Start();
for (int i = 0; i < N; ++i) generic_processor.process(derived);
sw.Stop();
Console.WriteLine("Sum ="+generic_processor.Sum + " Generic performance = " + sw.ElapsedMilliseconds + " millisec");
sw.Restart();
sw.Start();
for (int i = 0; i < N; ++i) polymorphic_processor.process(derived);
sw.Stop();
Console.WriteLine("Sum ="+polymorphic_processor.Sum+ " Poly performance = " + sw.ElapsedMilliseconds + " millisec");
Even more surprising (and confusing) is that if I add a type cast to the polymorphic version of processor as follows, it then runs consistently ~20% faster than the generic version.
public void process(Base trade)
{
sum += ((Derived)trade).Size; // cast not needed - just an experiment
}
What's going on here? I understand generics can help avoid costly boxing and unboxing when dealing with primitive types, but I'm dealing strictly with reference types here.
Execute the test under .NET 4.5 x64 with Ctrl-F5 (without debugger). Also with N increased by 10x. That way the results reliably reproduce, no matter what order the tests are in.
With generics on ref types you still get the same vtable/interface lookup because there's just one compiled method for all ref types. There's no specialization for Derived. Performance of executing the callvirt should be the same based on this.
Furthermore, generic methods have a hidden method argument that is typeof(T) (because this allows you to actually write typeof(T) in generic code!). This is additional overhead explaining why the generic version is slower.
Why is the cast faster than the interface call? The cast is just a pointer compare and a perfectly predictable branch. After the cast the concrete type of the object is known, allowing for a faster call.
if (trade.GetType() != typeof(Derived)) throw;
Derived.Size(trade); //calling directly the concrete method, potentially inlining it
All of this is educated guessing. Validate by looking at the disassembly.
If you add the cast you get the following assembly:
My assembly skills are not enough to fully decode this. However:
16 loads the vtable ptr of Derived
22 and #25 are the branch to test the vtable. This completes the cast.
at #32 the cast is done. Note, that following this point there's no call. Size was inlined.
35 a lea implements the add
39 store back to this.sum
The same trick works with the generic version (((Derived)(Base)o).Size).
I believe Servy was correct it is a problem with your test. I reversed the order of the tests (just a hunch):
internal class Program
{
public interface Base
{
Int64 Size { get; }
}
public class Derived : Base
{
public Int64 Size
{
get
{
return 10;
}
}
}
public class GenericProcessor<TT>
where TT : Base
{
private Int64 sum;
public GenericProcessor()
{
sum = 0;
}
public void process(TT o)
{
sum += o.Size;
}
public Int64 Sum
{
get
{
return sum;
}
}
}
public class PolymorphicProcessor
{
private Int64 sum;
public PolymorphicProcessor()
{
sum = 0;
}
public void process(Base o)
{
sum += o.Size;
}
public Int64 Sum
{
get
{
return sum;
}
}
}
private static void Main(string[] args)
{
var generic_processor = new GenericProcessor<Derived>();
var polymorphic_processor = new PolymorphicProcessor();
Stopwatch sw = new Stopwatch();
int N = 100000000;
var derived = new Derived();
sw.Start();
for (int i = 0; i < N; ++i) polymorphic_processor.process(derived);
sw.Stop();
Console.WriteLine(
"Sum =" + polymorphic_processor.Sum + " Poly performance = " + sw.ElapsedMilliseconds + " millisec");
sw.Restart();
sw.Start();
for (int i = 0; i < N; ++i) generic_processor.process(derived);
sw.Stop();
Console.WriteLine(
"Sum =" + generic_processor.Sum + " Generic performance = " + sw.ElapsedMilliseconds + " millisec");
Console.Read();
}
}
In this case the polymorphic is slower in my tests. This shows that the first test is significantly slower than the second test. It could be loading classes the first time, preemptions, who knows ...
I just want to note that I am not arguing that generics are faster or as fast. I'm simply trying to prove that these kinds of tests don't make a case one way or the other.
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.
In the following program, DummyMethod always print 5. But if we use the commented code instead, we get different values (i.e. 1, 2, 3, 4). Can anybody please explain why this is happenning?
delegate int Methodx(object obj);
static int DummyMethod(int i)
{
Console.WriteLine("In DummyMethod method i = " + i);
return i + 10;
}
static void Main(string[] args)
{
List<Methodx> methods = new List<Methodx>();
for (int i = 0; i < 5; ++i)
{
methods.Add(delegate(object obj) { return DummyMethod(i); });
}
//methods.Add(delegate(object obj) { return DummyMethod(1); });
//methods.Add(delegate(object obj) { return DummyMethod(2); });
//methods.Add(delegate(object obj) { return DummyMethod(3); });
//methods.Add(delegate(object obj) { return DummyMethod(4); });
foreach (var method in methods)
{
int c = method(null);
Console.WriteLine("In main method c = " + c);
}
}
Also if the following code is used, I get the desired result.
for (int i = 0; i < 5; ++i)
{
int j = i;
methods.Add(delegate(object obj) { return DummyMethod(j); });
}
The problem is that you're capturing the same variable i in every delegate - which by the end of the loop just has the value 5.
Instead, you want each delegate to capture a different variable, which means declaring a new variable in the loop:
for (int i = 0; i < 5; ++i)
{
int localCopy = i;
methods.Add(delegate(object obj) { return DummyMethod(localCopy); });
}
This is a pretty common "gotcha" - you can read a bit more about captured variables and closures in my closures article.
This article will probably help you understand what is happening (i.e. what a closure is): http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx
If you look at the code generated (using Reflector) you can see the difference:
private static void Method2()
{
List<Methodx> list = new List<Methodx>();
Methodx item = null;
<>c__DisplayClassa classa = new <>c__DisplayClassa();
classa.i = 0;
while (classa.i < 5)
{
if (item == null)
{
item = new Methodx(classa.<Method2>b__8);
}
list.Add(item);
classa.i++;
}
foreach (Methodx methodx2 in list)
{
Console.WriteLine("In main method c = " + methodx2(null));
}
}
When you use the initial code it creates a temporary class in the background, this class holds a reference to the "i" variable, so as per Jon's answer, you only see the final value of this.
private sealed class <>c__DisplayClassa
{
// Fields
public int i;
// Methods
public <>c__DisplayClassa();
public int <Method2>b__8(object obj);
}
I really recommend looking at the code in Reflector to see what's going on, its how I made sense of captured variables. Make sure you set the Optimization of the code to ".NET 1.0" in the Option menu, otherwise it'll hide all the behind scenes stuff.
I think it is because the variable i is put to the heap (it's a captured variable)
Take a look at this answer.
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.