There are two costs associated with use of delegates: construction and invocation. Invocation, thankfully, is comparable to a normal method call in nearly all circumstances, but delegates are objects and constructing them can be quite expensive. You want to pay this cost only once and cache the result.
Consider the following code:
private delegate int MathOp(int x, int y); private static int Add(int x, int y) { return x + y; } private static int DoOperation(MathOp op, int x, int y) { return op(x, y);}
Which of the following is aster?
Option 1:
for (int i = 0; i < 10; i++) { DoOperation(Add, 1, 2); }
Option 2 :
MathOp op = Add; for (int i = 0; i < 10; i++) { DoOperation(op, 1, 2); }
It looks like Option 2 is only aliasing the Add function with a local delegate variable, but this actually involves a memory allocation! It becomes clear if you look at the IL for the respective loops:Option 1:
// loop start (head: IL_0020) IL_0004: ldnull IL_0005: ldftn int32 DelegateConstruction.Program::Add(int32, int32) IL_000b: newobj instance void DelegateConstruction.Program/MathOp::.ctor(object, native int) IL_0010: ldc.i4.1 IL_0011: ldc.i4.2 IL_0012: call int32 DelegateConstruction.Program:: DoOperation(class DelegateConstruction.Program/MathOp, int32, int32) ...
While Option 2 has the same memory allocation, but it is outside of the loop:
L_0025: ldnull IL_0026: ldftn int32 DelegateConstruction.Program::Add(int32, int32) IL_002c: newobj instance void De legateConstruction.Program/MathOp::.ctor(object, native int) ... // loop start (head: IL_0047) IL_0036: ldloc.1 IL_0037: ldc.i4.1 IL_0038: ldc.i4.2 IL_0039: call int32 DelegateConstruction.Program::DoOperation(class DelegateConstruction.Program/MathOp, int32, int32) ...
For all your application development needs, visit www.verbat.com for a fiscally conscious proposal that meets your needs ( So I can keep this blog going as well!!!!)
Alternatively click through the link if you found this article interesting. (This will help the companies Search engine rankings)
Leave a Reply