Amazon.com Widgets

*VERY* poor man's profiler

There are tons of great .NET profilers out there, but my experince with customers is that very few are using them.  There are a varity of reasons for this, but if you are seroius about getting the best performance possible out of your managed apps you should be using one (or more) of them. 

 

But even if you are not super serois about the performance of your app, you should know what your app loads.   Here is a handy little tip Krzysztof used on a recent customer visit… I thought it was such a good idea, I’d share it with you. 

 

Just cut-and-paste this code into some steady state part of your app (on a button click, etc) and then read the log file it creates.  Do you know where all of those modules are coming from?  What benefit is your app getting from them?  Why are they there?

 

.NET Framework 2.0 code:

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            foreach (System.Diagnostics.ProcessModule pm in System.Diagnostics.Process.GetCurrentProcess().Modules)

            {

                sb.AppendLine(pm.FileName);

            }

            System.IO.File.WriteAll("C:\\ModulesLoadedLog.txt", sb.ToString());

 

 

.NET Framework 1.0 and 1.1 code:

        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        foreach (System.Diagnostics.ProcessModule pm in System.Diagnostics.Process.GetCurrentProcess().Modules)

        {

            sb.Append(pm.FileName + System.Environment.NewLine);

        }

        System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\ModulesLoadedLog.txt");

        sw.Write(sb.ToString());

        sw.Close();

 

(Note: the Observing a thing changes it principle does apply here. Do you know what modules the above code causes to be loaded?)

 

 

From a simple hello world app on V1.1 I get 25

D:\Documents and Settings\brada\Start Menu\Programs\Startup\foo.exe

D:\WINDOWS\system32\ntdll.dll

D:\WINDOWS\system32\mscoree.dll

D:\WINDOWS\system32\ADVAPI32.dll

D:\WINDOWS\system32\KERNEL32.dll

D:\WINDOWS\system32\RPCRT4.dll

D:\WINDOWS\system32\tsappcmp.dll

D:\WINDOWS\system32\msvcrt.dll

D:\WINDOWS\system32\SHLWAPI.dll

D:\WINDOWS\system32\GDI32.dll

D:\WINDOWS\system32\USER32.dll

D:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorwks.dll

D:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\MSVCR71.dll

D:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\fusion.dll

D:\WINDOWS\system32\ole32.dll

D:\WINDOWS\system32\SHELL32.dll

D:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.100.0_x-ww_8417450B\comctl32.dll

d:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll

d:\windows\assembly\nativeimages1_v1.1.4322\mscorlib\1.0.5000.0__b77a5c561934e089_a4297563\mscorlib.dll

D:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorsn.dll

D:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\MSCORJIT.DLL

d:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll

d:\windows\assembly\nativeimages1_v1.1.4322\system\1.0.5000.0__b77a5c561934e089_c7218c53\system.dll

D:\WINDOWS\system32\psapi.dll

 

And on V2.0 I get 20 (5 less!)

D:\Program Files\Microsoft Visual Studio 8\VC\foo.exe

D:\WINDOWS\system32\ntdll.dll

D:\WINDOWS\system32\mscoree.dll

D:\WINDOWS\system32\ADVAPI32.dll

D:\WINDOWS\system32\KERNEL32.dll

D:\WINDOWS\system32\RPCRT4.dll

D:\WINDOWS\system32\tsappcmp.dll

D:\WINDOWS\system32\msvcrt.dll

D:\WINDOWS\system32\SHLWAPI.dll

D:\WINDOWS\system32\GDI32.dll

D:\WINDOWS\system32\USER32.dll

D:\WINDOWS\Microsoft.NET\Framework\v2.0.41111\mscorwks.dll

D:\WINDOWS\Microsoft.NET\Framework\v2.0.41111\MSVCR80.dll

D:\WINDOWS\assembly\NativeImages_v2.0.41111_32\mscorlib\4b0ec1643e93f732a00f1ef4a3519a2a\mscorlib.ni.dll

D:\WINDOWS\system32\ole32.dll

D:\WINDOWS\system32\shell32.dll

D:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.100.0_x-ww_8417450B\comctl32.dll

D:\WINDOWS\Microsoft.NET\Framework\v2.0.41111\mscorjit.dll

D:\WINDOWS\assembly\NativeImages_v2.0.41111_32\System\f6276094994ff83d999dad8ef607a716\System.ni.dll

D:\WINDOWS\system32\psapi.dll

 

The log from the ScreenSaver that ships in the C# Express skus shows that I get 60+ modules loaded… Know what you are using…  

 

Published 15 November 04 09:41 by BradA
Filed under:

Comments

# Junfeng Zhang said on November 15, 2004 10:55 PM:
Did I count right? It is 24 in v1.1.

20 dlls is still way too much for helloworld.
# RichB said on November 15, 2004 11:24 PM:
So, whereas .Net 1.1 loads the NGen'd image, plus the image in the GAC (for metadata), .Net v2 doesn't load the image in the GAC.

Does that mean that ngen'd images have all the metadata they need to execute? Does that mean that ngen'd images can be deployed without their original assembly?
# Junfeng Zhang said on November 16, 2004 12:52 AM:
The answer is "No", of course.

We still need the IL images to do native image validation. But we don't load them anymore in Whidbey.

Only things going through LoadLibrary will show up in the output. This is the limitation of psapi.dll APIs.
# Jelle Druyts said on November 16, 2004 12:53 AM:
Good point by RichB: where'd the original assemblies go? Or does the metadata get injected into the .text section of the PE/COFF file again?

Other missing dll's in v2: mscorsn.dll (got merged into mscorwks.dll) and fusion.dll. I suppose fusion.dll must have been merged into something else as well, I can't imagine how you could load some of the listed modules without it ;-)

What I find peculiar is that despite it being a Console app (since System.Windows.Forms.dll isn't loaded), it still needs Windows stuff like GDI32.dll and comctl32.dll.

Regarding the Heisenberg question: what the code will *cause to be loaded* depends on the code that ran before it ;-) I don't think it actually *needs* anything beyond the usual suspects (mscorlib, System.dll & friends) though... But I'm obviously wrong since you asked in the first place :-)
# Ollie Riches said on November 16, 2004 5:23 AM:
Don't you just love refactoring :)

I always use a profiler now on projects, it has made my implementations in .Net much more efficient and I believe given me a better understanding of .Net and how you are meant to use framework....

I am always surprised that developers don't use them....
# Sam said on November 16, 2004 7:06 AM:
Ants is my favorite profiler, too bad I can't afford to buy it for my wee pet projects :/

Sam
# Brad Williams said on November 16, 2004 11:32 AM:
I'm not quite appreciating why it's important in general to know what your app loads. What are some reasons? Thanks in advance.
# RJ said on November 16, 2004 1:26 PM:
In this case observing doesn't have to change it. Just use one of the many tools that listis dlls in a process. Like Process Explorer from sysinternals.com. procexp even gives easy access to the .net perf counters for a process.

# Judah said on November 16, 2004 3:39 PM:
Are there any good profilers out there that work on the 2.0 beta? I love Red Gate's Antz .NET profiler, given that it has per-line timing which is great. Unfortunately, they don't have a beta that works on the 2.0 beta yet.
New Comments to this post are disabled

Search

Go

This Blog

Syndication

Page view tracker