How Does Having a Dynamic Variable Affect Performance

How does having a dynamic variable affect performance?


I've read dynamic makes the compiler run again, but what it does. Does it have to recompile whole method with the dynamic used as a parameter or rather those lines with dynamic behavior/context(?)

Here's the deal.

For every expression in your program that is of dynamic type, the compiler emits code that generates a single "dynamic call site object" that represents the operation. So, for example, if you have:

class C
{
void M()
{
dynamic d1 = whatever;
dynamic d2 = d1.Foo();

then the compiler will generate code that is morally like this. (The actual code is quite a bit more complex; this is simplified for presentation purposes.)

class C
{
static DynamicCallSite FooCallSite;
void M()
{
object d1 = whatever;
object d2;
if (FooCallSite == null) FooCallSite = new DynamicCallSite();
d2 = FooCallSite.DoInvocation("Foo", d1);

See how this works so far? We generate the call site once, no matter how many times you call M. The call site lives forever after you generate it once. The call site is an object that represents "there's going to be a dynamic call to Foo here".

OK, so now that you've got the call site, how does the invocation work?

The call site is part of the Dynamic Language Runtime. The DLR says "hmm, someone is attempting to do a dynamic invocation of a method foo on this here object. Do I know anything about that? No. Then I'd better find out."

The DLR then interrogates the object in d1 to see if it is anything special. Maybe it is a legacy COM object, or an Iron Python object, or an Iron Ruby object, or an IE DOM object. If it is not any of those then it must be an ordinary C# object.

This is the point where the compiler starts up again. There's no need for a lexer or parser, so the DLR starts up a special version of the C# compiler that just has the metadata analyzer, the semantic analyzer for expressions, and an emitter that emits Expression Trees instead of IL.

The metadata analyzer uses Reflection to determine the type of the object in d1, and then passes that to the semantic analyzer to ask what happens when such an object is invoked on method Foo. The overload resolution analyzer figures that out, and then builds an Expression Tree -- just as if you'd called Foo in an expression tree lambda -- that represents that call.

The C# compiler then passes that expression tree back to the DLR along with a cache policy. The policy is usually "the second time you see an object of this type, you can re-use this expression tree rather than calling me back again". The DLR then calls Compile on the expression tree, which invokes the expression-tree-to-IL compiler and spits out a block of dynamically-generated IL in a delegate.

The DLR then caches this delegate in a cache associated with the call site object.

Then it invokes the delegate, and the Foo call happens.

The second time you call M, we already have a call site. The DLR interrogates the object again, and if the object is the same type as it was last time, it fetches the delegate out of the cache and invokes it. If the object is of a different type then the cache misses, and the whole process starts over again; we do semantic analysis of the call and store the result in the cache.

This happens for every expression that involves dynamic. So for example if you have:

int x = d1.Foo() + d2;

then there are three dynamic calls sites. One for the dynamic call to Foo, one for the dynamic addition, and one for the dynamic conversion from dynamic to int. Each one has its own runtime analysis and its own cache of analysis results.

Make sense?

Does storing in variables increase performance? And do var, let, const also affect performance?

No, simply by storing a value in a variable does not increase the performance, in fact, there will be a slightly reduced performance since additional memory allocation and fetching happens.

However, storing the result of a computation in a variable and using the variable instead of re-computing it every time the values are required improves the performance.

Converting app.listen(3000) into below format does not have any performance benefit.

const port = 3000;
app.listen(port)

However, if the port values require some computation like,

const port = process.env.PORT || 3000;

then storing the result in a variable and using that values every time port number is required will have a performance benefit compared to computing it every time.

(In your example, since the port value is used only once, there is no point in storing the result in a variable.)

I heard, for example, it improves performance of loops.
Again, you have a performance benefit only if the value stored in the variable requires some form of computation.

const array = [1,2,3];
const length = array.length;
for (let i =0 ;i<length; i++) {
console.log(array[i]);
}

The above example has performance benefits compared to the one below.

const array = [1,2,3];
for (let i =0 ;i<array.length; i++) {
console.log(array[i]);
}

In this example, in every iteration of the loop, the length of the array has to be calculated which is not necessary since the array does not change.

And off-topic: isn't app.listen() function kinda a loop? Or does it use an inbuilt loop?

No, app.listen() is not a loop. It is an event listener. Internally the node event loop handles such I/O operations. You can read more about the event loop here.

C# Dynamic Keyword — Run-time penalty?

The question is very confusing.

Does defining an instance as dynamic in C# mean:

By "defining an instance" do you mean "declaring a variable"?

The compiler does not perform compile-time type checking, but run-time checking takes place like it always does for all instances.

What do you mean by "run-time checking like it always does"? What run-time checking did you have in mind? Are you thinking of the checking performed by the IL verifier, or are you thinking of runtime type checks caused by casts, or what?

Perhaps it would be best to simply explain what "dynamic" does.

First off, dynamic is from the perspective of the compiler a type. From the perspective of the CLR, there is no such thing as dynamic; by the time the code actually runs, all instances of "dynamic" have been replaced with "object" in the generated code.

The compiler treats expressions of type dynamic exactly as expressions of type object, except that all operations on the value of that expression are analyzed, compiled and executed at runtime based on the runtime type of the instance. The goal is that the code executed has the same semantics as if the compiler had known the runtime types at compile time.

Your question seems to be about performance.

The best way to answer performance questions is to try it and find out - what you should do if you need hard numbers is to write the code both ways, using dynamic and using known types, and then get out a stopwatch and compare the timings. That's the only way to know.

However, let's consider the performance implications of some operations at an abstract level. Suppose you have:

int x = 123;
int y = 456;
int z = x + y;

Adding two integers takes about a billionth of a second on most hardware these days.

What happens if we make it dynamic?

dynamic x = 123;
dynamic y = 456;
dynamic z = x + y;

Now what does this do at runtime? This boxes 123 and 456 into objects, which allocates memory on the heap and does some copies.

Then it starts up the DLR and asks the DLR "has this code site been compiled once already with the types for x and y being int and int?"

The answer in this case is no. The DLR then starts up a special version of the C# compiler which analyzes the addition expression, performs overload resolution, and spits out an expression tree describing the lambda which adds together two ints. The DLR then compiles that lambda into dynamically generated IL, which the jit compiler then jits. The DLR then caches that compiled state so that the second time you ask, the compiler doesn't have to do all that work over again.

That takes longer than a nanosecond. It takes potentially many thousands of nanoseconds.

Does that answer your questions? I don't really understand what you're asking here but I'm making a best guess.

Why use dynamic variables (variable variables) in PHP or other languages

I had voted to close this question (vote since retracted) on the basis of it being subjective, but on reflection, I think I can give an objective answer.

A static variable name is a sequence of characters, representing a token which the underlying engine uses as a label to identify the value the variable represents (very very layperson's description).

A "sequence of characters" is a string. A string is an expression that represents a string. So from there it stands to reason that any expression that represents a string ought to be good enough to represent the token that refers to a variable. And that expression itself could be assigned to a variable, and from there one gets dynamic variable names.

But this is not what you asked. You asked: why?

It's not for the implementors of the language to answer questions like that. It's their job to provide a uniform and predictable programming interface, via their language. It's uniform to be able to represent a sequence of characters via an expression which in turn could be represented by a variable. Job done.

Subjectively, I could potentially see where some data is imported from an external source, and even the schema of the data is dynamic. One might want to represent that in some sort of generic object fashion, and it leads from there that the names of the properties of the object might also be dynamic. Whether or not this might be a good approach to the problem at hand is entirely subjective, and down to the developer's judgement, and that of their peers during code review.

Another example might be that you've inherited some shoddy spaghetti code where "needs must" and using dynamic naming - for whatever reason - might be a good approach.

PHP's burden ends at providing the mechanism to write the code; it does not speak to the quality of the design of said code. That's what code review is for.

How's memory allocated for a dynamic variable .net 4.0?

A variable of type dynamic is effectively a variable of type object as far as the CLR is concerned. It only affects the compiler, which makes any operations using a dynamic expression go through execution-time binding.

That binding process itself will use extra local variables etc (take a look in ILDASM, Reflector or something similar and you'll be staggered) but in terms of dynamicVar itself, the code you've got is just like having an object variable - with appropriate boxing for the int and bool values.

Implications of Instantiating Objects with Dynamic Variables in PHP

One of the issues with the resolving at run time is that you make it really hard for the opcode caches (like APC). Still, for now, doing something like you describe in your question is a valid way if you need a certain amount of indirection when instanciating stuff.

As long as you don't do something like

$classname = 'SomeClassName';
for ($x = 0; $x < 100000; $x++){
$object = new $classname;
}

you are probably fine :-)

(my point being: Dynamically looking up a class here and then doesn't hurt. If you do it often, it will).

Also, be sure that $classname can never be set from the outside - you'd want to have some control over what exact class you will be instantiating.

Why use dynamic typing in c#?

var isn't dynamic typing. It's just that the type of aName is inferred by the compiler.

Your example is still entirely statically typed, and has no performance penalty. Your code is compiled into exactly the same IL as it would be with an explicit type name.

Now in C# 4, dynamic typing does exist, but it would be written as:

dynamic aName = new AClassName();

My personal belief is that dynamic typing will be relatively rarely useful in C# 4 - basically when you're dealing with data which is already only known dynamically, e.g. reflection, or navigating XML.



Related Topics



Leave a reply



Submit