Just In Time Question

P

Phill

I'm new to C# and so far I'm pretty happy with the language and the
design behind it. My only real concern is about performance.

I wanted to ask a question about how a program you build in Visual
studio gets handled.

After it is built you have what looks like an normal win32 exe. And at
least part of that code must be because it runs. Now I've read that
what happens is the JIT compiler compiles the portion of the program
that needs to be compiled to start the app. And that it only compiles
the rest as it is needed.

Now, assuming I'm right so far, my question is this:

Where is this compiled code going? Is it getting compiled into the
original exe file you built from Visual Studio so that the compiled
code is there for all time and JIT won't be needed ever again once it
is all compiled? Or is it being kept off on the side somewhere in .Net
Framework Land and will need to be recompiled when the machine
reboots?

Also, once the program is compiled is it as fast as a win32 program?

Thanks for any help.
 
J

Jon Skeet [C# MVP]

Phill said:
I'm new to C# and so far I'm pretty happy with the language and the
design behind it. My only real concern is about performance.

I wanted to ask a question about how a program you build in Visual
studio gets handled.

After it is built you have what looks like an normal win32 exe. And at
least part of that code must be because it runs. Now I've read that
what happens is the JIT compiler compiles the portion of the program
that needs to be compiled to start the app. And that it only compiles
the rest as it is needed.

Now, assuming I'm right so far, my question is this:

Where is this compiled code going? Is it getting compiled into the
original exe file you built from Visual Studio so that the compiled
code is there for all time and JIT won't be needed ever again once it
is all compiled? Or is it being kept off on the side somewhere in .Net
Framework Land and will need to be recompiled when the machine
reboots?

It's basically in memory, effectively. (It may get written out to disk
on a temporary file - I'm not sure.) The JIT compiler recompiles it
next time. You can use ngen.exe to "pre-JIT" it - although I believe
ngen can't optimise as heavily as the "real" JIT.
Also, once the program is compiled is it as fast as a win32 program?

Roughly. Maybe a bit slower. If you're very unlucky, you'll end up
doing something which is much slower than a well-optimised bit of
C/C++, and do it in a loop, lots of times. For most apps, however, it
doesn't make that much difference.
 
P

Phill

It's basically in memory, effectively. (It may get written out to disk
on a temporary file - I'm not sure.) The JIT compiler recompiles it
next time. You can use ngen.exe to "pre-JIT" it - although I believe
ngen can't optimise as heavily as the "real" JIT.


Roughly. Maybe a bit slower. If you're very unlucky, you'll end up
doing something which is much slower than a well-optimised bit of
C/C++, and do it in a loop, lots of times. For most apps, however, it
doesn't make that much difference.

OK, so why does the JIT work that way? Why did they think it was a
good idea to keep compiling programs over and over again? Why not have
the JIT only do it once? That doesn't make much sense to me.
 
J

Jon Skeet [C# MVP]

Phill said:
OK, so why does the JIT work that way? Why did they think it was a
good idea to keep compiling programs over and over again? Why not have
the JIT only do it once? That doesn't make much sense to me.

Well, it means that:

1) You don't need to be able to write to the disk in order to run the
program
2) You don't need to have complicated checks to make sure that the code
you JITted before is the same code you're running now
3) You can make optimisations based on (say) CPU which may be different
next time you run the code
 
P

Phill

So, it was done from the point of view of the program being on like a
file server and accessed by PCs remotely?
 
J

Jon Skeet [C# MVP]

Phill said:
So, it was done from the point of view of the program being on like a
file server and accessed by PCs remotely?

Well, it *might* be on a file server. Or it might be running from a
non-privileged account. Or it might be running on several PCs each with
a different processor.

It's possible that MS will add some kind of cache in the future, of
course.
 
S

Stu Smith

Jon Skeet said:
It's basically in memory, effectively. (It may get written out to disk
on a temporary file - I'm not sure.) The JIT compiler recompiles it
next time. You can use ngen.exe to "pre-JIT" it - although I believe
ngen can't optimise as heavily as the "real" JIT.


Roughly. Maybe a bit slower. If you're very unlucky, you'll end up
doing something which is much slower than a well-optimised bit of
C/C++, and do it in a loop, lots of times. For most apps, however, it
doesn't make that much difference.

Out of curiosity, what makes you think a bit of .NET code will be slower
than the equivalent bit of C/C++ code? (Frameworks aside).
 
J

Jon Skeet [C# MVP]

Stu Smith said:
Out of curiosity, what makes you think a bit of .NET code will be slower
than the equivalent bit of C/C++ code? (Frameworks aside).

It's a managed environment. Things like garbage collection can slow
things down a bit (although they can speed up some pathological cases
too) and the JIT compiler tends not to be quite as aggressive with its
optimisations (partly due to time constraints) as some C/C++ compilers.

Usually it's not enough to make a significant difference though.
 
M

Michel Walsh

Hi,

Was it not supposed to be a pre-JIT tool (NGEN ? ) that could indeed
produce an executable already compiled given a "configuration" ?


Vanderghast, Access MVP
 
J

Jon Skeet [C# MVP]

Michel Walsh said:
Was it not supposed to be a pre-JIT tool (NGEN ? ) that could indeed
produce an executable already compiled given a "configuration" ?

Yes, in theory ngen could take more time and optimise more aggressively
- although it still doesn't know all of the libraries that will be used
with that particular assembly etc.

In practice, I think ngen actually optimises *less* aggressively than
the normal JIT, although that's only remembered hearsay :)
 
P

Phill

Out of curiosity, what makes you think a bit of .NET code will be slower
than the equivalent bit of C/C++ code? (Frameworks aside).

Well it doesn't necessarily have to be faster, In fact using .Net
would likely help the criminally negligent to write more efficient
code than they would in other settings.

But given a knowledgable C/C++ programmer you just can't beat the
speed you can get. Because no run time is babysitting your actions you
can be much faster. As Good as the run-time in .net is, it can't know
as much about your program as you do. Therefore if you have total
control over it you can be more efficient.

Pointers are very efficient. Using int as a bool and all the stuff
modern languages are trying to get rid of actually allow you to write
faster code. Potentially unsafe code mind you if you don't know what
you are doing, but potentially faster code all the same.

Granted, it is not always important to be bleeding fast. Sometimes it
is. All the same I can't help but want to be as efficient as is
practical. It's just my nature.

Anyway Thanks for answering my questions about the JIT. Still seems
wierd to me to not keep the compiled version of the program around
unless the program had been overwritten. If I was the runtime on a
desktop I think I'd compile it in another file until the whole program
was finished and then when it was totally compiled copy it over the
original managed code file and just use the win32 version from that
point on.
 
S

Stu Smith

Phill said:
Well it doesn't necessarily have to be faster, In fact using .Net
would likely help the criminally negligent to write more efficient
code than they would in other settings.

These discussions remind me about the change-over from C to C++. People
complained that C++ was doing too much 'under the hood', and that C would
always be quicker. Of course we now know that a combination of better
compiler technology, language features (eg C sort vs C++ sort) and libraries
(eg printf vs iostream) gives C++ a performance edge over standard C.
But given a knowledgable C/C++ programmer you just can't beat the
speed you can get. Because no run time is babysitting your actions you
can be much faster. As Good as the run-time in .net is, it can't know
as much about your program as you do. Therefore if you have total

I would have thought it can know more. You don't know whether your program
is running on a single or dual processor machine, so you have to include
synchronisation operations. Under .NET they can become no-ops if the runtime
realises the app is being run on a single-processor machine.
control over it you can be more efficient.

Don't forget that C++ has the equivalent of a runtime. When you write
something like:

// C++
{
vector<int> v;

...
}

// C#
{
List<int> v = new List<int>();

...
}

You're allocating memory, and initialising it, and then at some point in the
future (that point obviously being the close brace in C++), deallocating
memory. The fact that the deallocation in .NET is handled by a 'runtime',
while the C++ one is handled by compiler-emitted code, doesn't make one
better or worse than the other. (Another example would be unwinding the
stack after an exception).

People get hung up about '% time spent in GC' but they forget that C++
new/delete are expensive operations -- profile a large C++ app and I
wouldn't be suprised to see these functions account for 5-10% of the total
time.

Remember that .NET is running compiled, native code. The only time that it
isn't under your control is when it's the GC thread, and handled correctly,
a collection is quick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top