Coding for Performance : Dynamic


It should probably go without saying, but to make it explicit: any code using the dynamic keyword, or the Dynamic Language Runtime (DLR) is not going to be highly optimized. Performance tuning is often about stripping away abstractions, but using the DLR is adding one huge abstraction layer. It has its place, certainly, but a fast system is not one of them.
When you use dynamic, what looks like straightforward code is anything but.

Take a simple, admittedly contrived example:


static void Main(string[] args)

{

int a = 13;

int b = 14;

int c = a + b;

Console.WriteLine(c);

}

The IL for this is equally straightforward:


.method private hidebysig static

void Main (

string[] args

) cil managed

{

// Method begins at RVA 0x2050

// Code size 17 (0x11)

.maxstack 2

.entrypoint

.locals init (

[0] int32 a,

[1] int32 b,

[2] int32 c

)

IL_0000: ldc.i4.s 13

IL_0002: stloc.0

IL_0003: ldc.i4.s 14

IL_0005: stloc.1

IL_0006: ldloc.0

IL_0007: ldloc.1

IL_0008: add

IL_0009: stloc.2

IL_000a: ldloc.2

IL_000b: call void [mscorlib]System.Console::WriteLine(int32) IL_0010: ret

} // end of method Program::Main

Now let’s just make those ints dynamic:


static void Main(string[] args)

{

dynamic a = 13;

dynamic b = 14;

dynamic c = a + b;

Console.WriteLine(c);

}

For the sake of space, I am actually going to not show the IL here, but this is what it looks like when you convert it back to C#:


private static void Main(string[] args)

{

object a = 13;

object b = 14;

if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)

{

Program.<Main>o__SiteContainer0.<>p__Site1 =

CallSite<Func<CallSite, object, object, object>>. Create(Binder.BinaryOperation(CSharpBinderFlags.None,

ExpressionType.Add,

typeof(Program),

new CSharpArgumentInfo[]

{

CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)

}));

}

object c = Program.<Main>o__SiteContainer0.

<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, a, b);

if (Program.<Main>o__SiteContainer0.<>p__Site2 == null)

{

Program.<Main>o__SiteContainer0.<>p__Site2 =

CallSite<Action<CallSite, Type, object>>. Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded,

"WriteLine",

null,

typeof(Program),

new CSharpArgumentInfo[]

{

CSharpArgumentInfo.Create(

CSharpArgumentInfoFlags.UseCompileTimeType |

CSharpArgumentInfoFlags.IsStaticType,

null),

CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)

}));

} Program.<Main>o__SiteContainer0.<>p__Site2.Target(

Program.<Main>o__SiteContainer0.<>p__Site2, typeof(Console), c);

}

Even the call to WriteLine isn’t straightforward. From simple, straightforward code, it has gone to a mishmash of memory allocations, delegates, dynamic method invocation, and these objects called CallSites.

I do not mean to dump too much on the DLR. It is a perfectly fine framework for rapid development and scripting. It opens up great possibilities for interfacing between dynamic languages and .NET. If you are interested in what it offers, read a good overview at http://www.writinghighperf.net/go/24.

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)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s