Dynamic Lang. Runtime VS Reflection

Dynamic Lang. Runtime vs Reflection

Readable\Maintainable code

Certainly true in my experence.

Fewer lines of code.

Not significantly, but it will help.

Affects application performance.

Very slightly. But not even close to the way reflection does.

Dynamic keyword is internally a wrapper of Reflection.

Completely untrue. The dynamic keyword leverages the Dynamic Library Runtime.

[Edit: correction as per comment below]

It would seem that the Dynamic Language Runtime does use Reflection and the performance improvements are only due to cacheing techniques.

Dynamic typing might turn into breeding ground for hard to find bugs.

This may be true; it depends how you write your code. You are effectively removing compiler checking from your code. If your test coverage is good, this probably won't matter; if not then I suspect you will run into problems.

Affects interoperability with previous .NET versions

Not true. I mean you won't be able to compile your code against older versions, but if you want to do that then you should use the old versions as a base and up-compile it rather than the other way around. But if you want to use a .NET 2 library then you shouldn't run into too many problems, as long as you include the declaration in app.config / web.config.

One significant pro that you're missing is the improved interoperability with COM/ATL components.

Performance dynamic vs Reflection

The easiest way to do this IMO is to define an interface that has an int Id {get;} property and have your types implement it. Then code to the interface. If your existing code is generic you might even be able to add awhere T : IYourInterface constraint, but you can cast to IYourInterface either way (assuming T actually does implement the interface).

If interfaces aren't an option:

Reflection and dynamic both have overheads; dynamic has better optimization (re-using a cached strategy).

If your items list is strongly typed to a specific T (where T is unknown here), then you can possibly further optimize this concept using LINQ expressions to compile delegates:

static class IdFetcher
{
public static int Fetch<T>(T item) => IdFetcher<T>.Fetch(item);
}
static class IdFetcher<T>
{
public static int Fetch(T item) => fetch(item);
static readonly Func<T, int> fetch;
static IdFetcher()
{
var p = Expression.Parameter(typeof(T), "item");
fetch = Expression.Lambda<Func<T, int>>(
Expression.PropertyOrField(p, "Id"), p).Compile();
}
}

Then just use IdFetcher<T>.Fetch(obj) or IdFetcher.Fetch(obj) (the first is more direct; the second is useful for anonymous types where you can't specify the T)

Other than that: if you want to know which is faster: time them (for large numbers of iterations).

Dynamic cast vs reflection invoke: which poison to pick?

Well, I was curious so I wrote a little program to test:

        var sw = new Stopwatch();
int loopLimit = 10000000;
object hint1;
sw.Start();
for( var i = 0; i < loopLimit; i++ )
hint1 = ( ( dynamic )theObject ).ToString();
sw.Stop();
Console.WriteLine( "dynamic time: {0}", sw.ElapsedMilliseconds );
sw.Restart();
for( var i = 0; i < loopLimit; i++ )
hint1 = method.Invoke( theObject, null );
sw.Stop();
Console.WriteLine( "invoke time: {0}", sw.ElapsedMilliseconds );
Console.ReadLine();

Playing with different values of loopLimit you'll see that for a relatively low number of calls Invoke is faster. As you increase loopLimit the dynamic call catches up and then it becomes much faster. Why? Because a dynamic call caches the Expression tree required to do the operation. And in this case, there is only one Expression tree created as I didn't change theObject (at a call site there will be only one Expression tree per object type).

So, long story short, if you are only calling a few thousand times or if you have a large variety of object types to test and call, then the Expression tree creation is going to kill your performance and Invoke will be better. If objects can be one of a few types and your method is called millions of times, then you may be better off with dynamic calls.

Play with the numbers for your particular situation. My guess is that you'll pick Invoke.

What is reflection and why is it useful?

The name reflection is used to describe code which is able to inspect other code in the same system (or itself).

For example, say you have an object of an unknown type in Java, and you would like to call a 'doSomething' method on it if one exists. Java's static typing system isn't really designed to support this unless the object conforms to a known interface, but using reflection, your code can look at the object and find out if it has a method called 'doSomething' and then call it if you want to.

So, to give you a code example of this in Java (imagine the object in question is foo) :

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

One very common use case in Java is the usage with annotations. JUnit 4, for example, will use reflection to look through your classes for methods tagged with the @Test annotation, and will then call them when running the unit test.

There are some good reflection examples to get you started at http://docs.oracle.com/javase/tutorial/reflect/index.html

And finally, yes, the concepts are pretty much similar in other statically typed languages which support reflection (like C#). In dynamically typed languages, the use case described above is less necessary (since the compiler will allow any method to be called on any object, failing at runtime if it does not exist), but the second case of looking for methods which are marked or work in a certain way is still common.

Update from a comment:

The ability to inspect the code in the system and see object types is
not reflection, but rather Type Introspection. Reflection is then the
ability to make modifications at runtime by making use of
introspection. The distinction is necessary here as some languages
support introspection, but do not support reflection. One such example
is C++

Compiled dynamic language

Probably there is a reason Lisp is like it is? Lisp was designed to program other languages and to compute with symbolic representations of code and data. The boundary between code and data is no longer there. This influences the design AND the implementation of a programming language.

Lisp has got its syntactical features to generate new code, translate that code and execute it. Thus pre-parsed code is also using the same data structures (symbols, lists, numbers, characters, ...) that are used for other programs, too.

Lisp knows its data at runtime - you can query everything for its type or class. Classes are objects themselves, as are functions. So these elements of the programming language and the programs also are first-class objects, they can be manipulated as such. Dynamic language has nothing to do with 'dynamic typing'.

'Dynamic language' means that the elements of the programming language (for example via meta classes and the meta-object protocol) and the program (its classes, functions, methods, slots, inheritance, ...) can be looked at runtime and can be modified at runtime.

Probably the more of these features you add to a language, the more it will look like Lisp. Since Lisp is pretty much the local maximum of a simple, dynamic, programmable programming language. If you want some of these features, then you might want to think which features of your other program language you have to give up or are willing to give up. For example for a simple code-as-data language, the whole C syntax model might not be practical.

So C-like and 'dynamic language' might not really be a good fit - the syntax is one part of the whole picture. But even the C syntax model limits us how easy we can work with a dynamic language.

Difference between Reflection and Late Binding in java with real time examples

Late binding (also known as dynamic dispatch) does not need reflection -- it still needs to know which member to dynamically bind to at compile-time (i.e. the signature of the member is known at compile-time), even though the binding to overridden members happens at run-time.

When doing reflection, you don't even know which member you're using (not even the name is known at compile-time, let alone the signature) -- everything happens at run-time, so it's a lot slower.

Static languages and Reflection

I think wikipedia explanation is not really phrased well.

Reflection (or introspection) is not about creation of code during runtime but rather about ability of code to reflect on itself in runtime (and modify it's behavior based on this). Examples would be getting info about type of the object (like RTTI in C++) or getting metadata associated with object (like annotations in Java).

Runtime code generation is more related to first-classness than to reflection, so I would argue that current wikipedia article is kind of misleading.

UPDATE

In other words answer to this:

Ok, now, my question is, how can static language (without eval ability) can have reflection (e.g Java)?

... would be that reflection does not rely on evel ability. These are 2 separate language features.

And also, as Giulio Franco pointed out in the comments - Java is capable of runtime code generation\manipulation (see CGLIB for example).

DLR and reflection

The return type of GetSomeObject() will be an instance of some type. For example, here's what it might look like:

public Customer GetSomeObject() {
return new Customer("John", "Doe", 12345);
}

And then the code would say:

dynamic customer = GetSomeObject();
string s = customer.FirstName;
// now the "s" variable would have "John" in it

The GetSomeObject() can return anything. It might return a Customer object or a Product. And it doesn't matter! The idea is that when the variable is declared as being dynamic that when you call a method or a property, as you have shown, the compiler will generate code that uses Reflection to try and call the method or property. If they exist then the calls will succeed. If not then you'll get an error at runtime.

In the general case this example is just simplifying the usage of Reflection by having the compiler generate the code for you.

Having said that, if the Customer or Product object implement IDynamicObject themselves then they can do far more advanced stuff.



Related Topics



Leave a reply



Submit