Share via


*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…

Comments

  • Anonymous
    November 15, 2004
    Did I count right? It is 24 in v1.1.

    20 dlls is still way too much for helloworld.
  • Anonymous
    November 15, 2004
    The comment has been removed
  • Anonymous
    November 15, 2004
    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.
  • Anonymous
    November 15, 2004
    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 :-)
  • Anonymous
    November 15, 2004
    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....
  • Anonymous
    November 15, 2004
    Ants is my favorite profiler, too bad I can't afford to buy it for my wee pet projects :/

    Sam
  • Anonymous
    November 16, 2004
    I'm not quite appreciating why it's important in general to know what your app loads. What are some reasons? Thanks in advance.
  • Anonymous
    November 16, 2004
    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.

  • Anonymous
    November 16, 2004
    The comment has been removed