I have an application that is showing a significant JIT overhead time. I know this application calls into a DLL that has a function with 10000 lines of code. So, I am sure it takes a while to JIT that when it is called the first time.

However, the Profiler seems to be indicating a tremendous amount of JIT time when calling this code. I would like to be able to determine which functions/DLLs are being JITed during execution.

My guy feeling is that the Profiler is causing the application to JIT the same code over and over again because when I run the application outside of the Profiler I don't see as much overhead.

Does anyone know if this is possible? Is there a setting for this? Any other tool that would show this?

Another thing I noticed was that the application uses Reflection and calls Invoke on the objects that keep on getting JITed. When I run this code without profiling, I don't see a noticeable performance hit like I do when running ANTS. When I use the Profiler, it seems to be JITing all the time.

I am testing compiling the application to have direct references to the DLLs that normally get loaded using Invoke. But I still wish I could find out more data about What is being JITed and When so I have a better understading of why I see all that JIT time.

I'm afraid I don't know the specific reasons, but you are right -- when I put perfmon on an assembly that I'd built, it spends about 5% of its time in the JIT. When it's being profiled, it leaps to 80% in some places. I thought maybe the IL injection was to blame, but method-level profiling still used the JIT just as much.

One thing I do know is that Profiler disables native images. If native images are loaded, certain notifications aren't sent by the .NET runtime that Profiler needs. It would make sense that without native images, you would have to JIT every method at least once.

That's a bummer. Do you know if the .NET profiling API exposes more details about the JITing? Any chance those details could be added to a future version of ANTS?

I know that the application I am testing does not use any NGEN'd assemblies (assuming that's the only way to "create" native images; my .NET knowledge isn't really deep). We do use a background thread and use Reflection's LoadAssembly() to pre-JIT DLLs we will be using later in the application and store it in an array. And this works beautifully at runtime. But profiling seems to consider all of that logic as unJITed everytime we grab an assembly from that runtime cache and so it skews our profiling results.

The profiler does perform several actions that can cause additional load on the JIT that it won't fully account for: in particular, it needs to add instrumentation and read debugging information. The instrumentation is particularly difficult to compensate for, as there's no way to know the time to compile a method without it.

This can be especially slow if the pdb or source files are located on a network drive.

There's no way to entirely eliminate this overhead, but you can reduce it by changing the profiler options. Switching to using one of the method-level modes will have the biggest effect, as it cuts down the amount of instrumentation significantly. Disabling the 'include source code with saved results' option will also increase JIT performance somewhat.

The biggest time waster after this is the time taken to read the debugging data for each function: unfortunately this can't be helped other than by removing PDB files for assemblies that you don't want source code information for.