dynamic language performance

18
Dynamic Language Performance or How I Learned to Love Metaprogramming W. Kevin Hazzard, C# MVP NoVA Code Camp October 2009

Upload: kevin-hazzard

Post on 22-Jul-2015

1.008 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Dynamic Language Performance

Dynamic Language Performanceor How I Learned to Love Metaprogramming

W. Kevin Hazzard, C# MVPNoVA Code Camp

October 2009

Page 2: Dynamic Language Performance

Agenda

• MetaObjects and MetaProgramming

• Dynamic Language Runtime Architecture

• The dynamic keyword in C# 4

• The CallSite<T> Class

• The CSharp RuntimeBinder

• DynamicMetaObjects

• Adaptive Inline Caching

• Demonstrations– Fluent XML Parsing

– Performance of Python to C# Integration

Page 3: Dynamic Language Performance

Metaobject Visualization

Users and programs interact

with metaobjects, not directly

with their backing objects.

control

create

invoke

Page 4: Dynamic Language Performance

DLR Architecture

Page 5: Dynamic Language Performance

The dynamic Keyword

• Is dynamic a new type? No

• The dynamic type is totally static

• This type is a signal to the compiler to perform late binding

dynamic DX = someFunction();

DX( ‘A’ );

DX.Foo( 1 );

DX.Bar = ‘X’;

int V = DX.Baz;

DX[0] = 100;

string S = DX[0];

[Dynamic] object DX = someFunction();

// invoke the object

// invoke the Foo member

// set the Bar member

// convert the Baz member to integer

// set index 0 to 100

// convert index 0 to string

Page 6: Dynamic Language Performance

Let's Stop and Reflect

class Program {

dynamic Jabberwocky( dynamic arg ) {

return arg.foo();

}

}

[return: Dynamic] object Jabberwocky( [Dynamic] object arg ) {

if (<Jabberwocky>o__SiteContainer2.<>p__Site3 == null) {

<Jabberwocky>o__SiteContainer2.<>p__Site3 =

CallSite<Func<CallSite, object, object>>.Create(

new CSharpInvokeMemberBinder( CSharpCallFlags.None,

"foo", typeof( Program ), null,

new CSharpArgumentInfo[] {

new CSharpArgumentInfo(

CSharpArgumentInfoFlags.None, null ) } ) );

}

return <Jabberwocky>o__SiteContainer2.<>p__Site3.Target(

<Jabberwocky>o__SiteContainer2.<>p__Site3, arg );

}

Page 7: Dynamic Language Performance

The CallSite<T> Class

• In the System.Runtime.CompilerServices

namespace

• Created and managed in a static container

class for each venue

• Key members:

– Create – creates and assign a binder

– Target – a delegate that invokes the binder

– Binder – connects an appropriate metaobject to

the underlying call implementation

Page 8: Dynamic Language Performance

The CSharp RuntimeBinder

What might these describe?

• Semantic Checker

• Symbol Table

• Expression Tree Creator

• Expression Factory

• Context Info

• Controller

• Dispatcher

Page 9: Dynamic Language Performance

What is a metaobject?

An object that:

• Creates

• Controls

• Invokes

• Describes

• Implements

May contain info on the:

• Interfaces of

• Type of

• Methods of

• Fields of

• Properties of

• Attributes of

… another object

Page 10: Dynamic Language Performance

The DynamicMetaObject Class

• BindCreateInstance

• BindBinaryOperation

• BindUnaryOperation

• BindConvert

• BindDeleteMember

• BindDeleteIndex

• BindInvoke

• BindInvokeMember

• BindGetMember

• BindSetMember

• BindGetIndex

• BindSetIndex

Binds up “The Twelve" DLR methods

All expression tree-oriented

Page 11: Dynamic Language Performance

IDynamicMetaObjectProvider

• Pattern for implementing a custom metaobject

• The returned DynamicMetaObject must implement all twelve binding methods (and more)

• Lots of Expression Tree knowledge is required

• Not a trivial exercise

public interface IDynamicMetaObjectProvider

{

DynamicMetaObject GetMetaObject(

Expression parameter );

}

Page 12: Dynamic Language Performance

DynamicObject to the rescue!

public class DynamicObject : IDynamicMetaObjectProvider {

protected DynamicObject();

public virtual DynamicMetaObject GetMetaObject(...);

public virtual bool TryBinaryOperation(...);

public virtual bool TryConvert(...);

public virtual bool TryCreateInstance(...);

public virtual bool TryDeleteIndex(...);

public virtual bool TryDeleteMember(...);

public virtual bool TryGetIndex(...);

public virtual bool TryGetMember(...);

public virtual bool TryInvoke(...);

public virtual bool TryInvokeMember(...);

public virtual bool TrySetIndex(...);

public virtual bool TrySetMember(...);

public virtual bool TryUnaryOperation(...);

}

Page 13: Dynamic Language Performance

Example – Fluent XML Parsing

<books pubdate="2009-06-15">

<book price="45.99" title="Surgery for Dummies">

<id isbn10="4389880339"/>

<authors>

<author>

<name>

<first>Mortimer</first>

<last>Snerdly</last>

</name>

<email address="[email protected]"/>

</author>

</authors>

</book>

</books>

Wouldn't it be nice if we could read and write XML like a set of nested objects without deep knowledge of the XML DOM or LINQ to XML?

WriteLine( books.book[0].authors.author[0].name.first );

Page 14: Dynamic Language Performance

FLUENT XML PARSING IN C#

Demonstration

Page 15: Dynamic Language Performance

Adaptive Inline Caching

• Each CallSite uses 3 levels of caching

– Level 0 – a dynamically generated delegate

for some of the call patterns encountered at

the site

– Level 1 – a read-only set of rules for all of the

call patterns that the site has seen so far

– Level 2 – a read-only set of rules that spans

multiple call sites

Page 16: Dynamic Language Performance

What about level 2 cache misses?

• A level 2 cache miss causes:

– The creation of a new rule

– The insertion of the new rule into the level 2

cache (on the ActionBinder)

– The insertion of the new rule into the level 1

cache (on the CallSite rule set)

– Possible insertion into the level 0 cache (on

the CallSite dynamic delegate)

Page 17: Dynamic Language Performance

PERFORMANCE OF

PYTHON TO C# INTEGRATION

Demonstration

Page 18: Dynamic Language Performance

For More Information

blogs.msdn.com/curth

blogs.msdn.com/cburrows

blogs.msdn.com/mmaly

www.gotnet.biz/Blog

www.voidspace.org.uk

blogs.msdn.com/samng