Tech Off Thread

13 posts

Visual Studio Performance Analysis in 10 minutes

Back to Forum: Tech Off
  • User profile image
    joshnuss

    Ever wondered how much time you spend waiting for Visual Studio to respond?
    Well its been driving me nuts for a while so I wrote a little app to tracks the time that VS 2008 spends "not responding".
    I think you'll be shocked by the results on solutions with 15+ projects.

    Hopefully making this information available to others will motivate Microsoft to fix these problems.

    Heres the code for your enjoyment (tested with VS 2008)..

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;

    namespace CalulateHangTime
    {
    [Flags]
    public enum SendMessageTimeoutFlags : uint
    {
    SMTO_NORMAL = 0x0000,
    SMTO_BLOCK = 0x0001,
    SMTO_ABORTIFHUNG = 0x0002,
    SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
    }

    public static class ExternalMethods
    {
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg,
    UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags,
    uint uTimeout, out UIntPtr lpdwResult);
    }

    class Program
    {
    static readonly uint WAIT_MILLISECONDS = 2;
    static readonly int SLEEP_MILLISECONDS = 1000;

    static void Main(string[] args)
    {
    long seconds = 0;
    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();
    while (true)
    {
    IntPtr hWnd = ExternalMethods.FindWindow("wndclass_desked_gsk", null);
    if (hWnd == IntPtr.Zero)
    throw new InvalidOperationException("Handle to window could not be found");


    UIntPtr result;
    IntPtr success = ExternalMethods.SendMessageTimeout(hWnd, 0, UIntPtr.Zero, IntPtr.Zero,
    SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, WAIT_MILLISECONDS, out result);

    if (success == IntPtr.Zero)
    {
    seconds += SLEEP_MILLISECONDS / 1000;

    Console.WriteLine("Visual Studio is hung. {0}/{1} seconds wasted", seconds, stopWatch.Elapsed.TotalSeconds);
    }
    else
    {
    Console.WriteLine("Visual Studio is running fine.");
    }

    Thread.Sleep(SLEEP_MILLISECONDS);
    }
    }
    }
    }

  • User profile image
    jh71283


    <Rant>
    The part that I find most irritating, is the fact the compilation hangs the GUI!

    If you have a fairly large project, then compiling takes time, we accept that.

    But why does it hand the gui? It is being done on a sperate thread, which we can tell by the fact that *sometimes* it is possible to cancel the build from the build menu.

    I just don't think they've spend much time on the threading when it comes to building the project, and so there are thousands of developer hours wasted by this silly scenario



    </Rant>

  • User profile image
    littleguru

    Heh. Interesting project. Although I never experience the problems, might be that my projects are to small perhaps.

  • User profile image
    yelatia

    Funny and nicely done. Good job cheers

  • User profile image
    David Berg

    Joshua,

    I just saw your post and looked at your code.  It's an interesting way to measure performance, but I think you're unfairly assuming that any non-success code is due to a hang situation; however, it could also be due to a timeout, which you've set to only 2ms.

    So what's happening is this - every second you take the pulse of VS, and if at that particular instant in time, it's doing anything that takes longer than 2 ms, then you're counting the entire second as being hung.  I don't think that's really fair.

    As a general rule of thumb, I tell people that it's okay to hang the UI thread for up to 100 ms during typing (although I prefer they keep it to under 50ms) and up to 4000 ms when displaying a dialog box (although I prefer they keep it well under 2000 ms).

    Of course, I'm not saying that VS doesn't have some performance issues that we need to address, just that I don't think they're as bad as your program implies.

    If you'd like to discuss the issue further, you can e-mail me at DevPerf@Microsoft.com.

    Regards,

    David Berg
    Microsoft Developer Division
    Performance Engineering Team

  • User profile image
    David Berg

    jh71283,

    Yes, it's unfortunate that compilation hangs the UI.  We need to fix it.  For what it's worth, it's  a multi-stage process, and most of it is (unfortunately) done on the UI thread, which is why it hangs and why the cancel button doesn't work.

    The time when it does work is only one small part of the overall process that actually checks...

    Again, as I said, we need to fix it (and everything else like it).

    Regards,

    David Berg
    Microsoft Developer Division
    Performance Engineering Team

  • User profile image
    jh71283

    Oh well, at least you guys are aware and working on it...

    I does beg the queston though why the decision was made to compile on the ui thread though... oh well!

  • User profile image
    andur

    As pointed out, that's not a very fair measurement.

    I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt

  • User profile image
    figuerres

    David Berg wrote:
    

    jh71283,

    Yes, it's unfortunate that compilation hangs the UI.  We need to fix it.  For what it's worth, it's  a multi-stage process, and most of it is (unfortunately) done on the UI thread, which is why it hangs and why the cancel button doesn't work.

    The time when it does work is only one small part of the overall process that actually checks...

    Again, as I said, we need to fix it (and everything else like it).

    Regards,

    David Berg
    Microsoft Developer Division
    Performance Engineering Team



    Hey, thanks for posting and showing that someone @ msft saw the post etc...

    most of the time I *LOVE* using VS but there are some places where it could use some love Smiley

    BTW:  on Vista I *HATE* it when the "Help update" locks up things.
    also the "White Screen" stage when someting has stolen the UI thread or whatever it is doing behind the curtain....
    does not happen real often but sure makes it *LOOK* like it crashed and has frozen... needs a dialog to say "VS 200x Pro is busy, Please wait..." to tell the dev it is busy and not totaly crashed.

  • User profile image
    AndyD


    andur wrote:
    As pointed out, that's not a very fair measurement.

    I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt


    No it doesn't. I can't think of anything worse than constantly being asked if I really want to rebuild when that's what I actually want to do. What would help though is not having the two options right next to each other. Try rearranging the menu options and see if that works better for you.

  • User profile image
    Isshou

    AndyD wrote:
    
    andur wrote:
    As pointed out, that's not a very fair measurement.

    I do know however, that I've wasted a *lot* of time by accidentally pressing "Rebuild Solution" instead of "Build Solution" in the build menu. "Rebuild Solution" really, really needs a "Yes/No are you sure" prompt


    No it doesn't. I can't think of anything worse than constantly being asked if I really want to rebuild when that's what I actually want to do. What would help though is not having the two options right next to each other. Try rearranging the menu options and see if that works better for you.


    It's always interesting to see comments like this. One feature that is a waste to someone else (for whatever reason) it a vital tool to someone else. Changes based on one person/groups perspectives is never a good thing, especially when it's something that you can work around already.


    As for the topic, along with counting potentially 998 extra milliseconds for each non-responsive event or even 1000 milliseconds for any non-success condition, the original test code counts not only the sleeping (1 second) but execution of the code for the total seconds. Since there is some marshaling done in it, it's not guaranteed to be quick, though in you're worst case event (waiting 2 milliseconds). Your count would be skewed because the stopwatch will count for at least 1002 milliseconds for ever 1 seconds you add to the "wasted time". That's ignoring the fact that Thread.Sleep(1000) is only a guarantee that it will sleep for at least 1000 milliseconds not that it will wake up in exactly 1000 milliseconds. It could be delayed even longer if a higher priority thread preempts it even after it returns to the ready state. Note that these things may actually skew the analysis to be lower than what it really is. However it still means the "analysis" is faulty.

    It should have been developed as the Tick/TimeElapsed event of one of the timers rather than a loop with Thread.Sleep. Or some other method of timing that is more accurate than relying on the Sleep method should have been used.

    Peter Richie had a blog post about Thread.Sleep and why it is useless for keeping time and other abuses of it.

    This is in addition to changes that would be needed to reconcile adding one whole second for any reason for the failed call.

  • User profile image
    kurt_godel

    Nice project Joshua.

    I have not used VS2008 yet but my VS2005 has such kind of problems (not with compiling but with starting/ending time)
    I never understood while loading (even to the blank project) or unloading should take so much time. I have set it not to load any project but still it takes me 10-15 secs to launch it.

    In comparison, Netbeans is terrible in the loading phase but closes very fast. Anyway, VS is still the best.

  • User profile image
    joshnuss

    David Berg said:
    Joshua,

    I just saw your post and looked at your code.  It's an interesting way to measure performance, but I think you're unfairly assuming that any non-success code is due to a hang situation; however, it could also be due to a timeout, which you've set to only 2ms.

    So what's happening is this - every second you take the pulse of VS, and if at that particular instant in time, it's doing anything that takes longer than 2 ms, then you're counting the entire second as being hung.  I don't think that's really fair.

    As a general rule of thumb, I tell people that it's okay to hang the UI thread for up to 100 ms during typing (although I prefer they keep it to under 50ms) and up to 4000 ms when displaying a dialog box (although I prefer they keep it well under 2000 ms).

    Of course, I'm not saying that VS doesn't have some performance issues that we need to address, just that I don't think they're as bad as your program implies.

    If you'd like to discuss the issue further, you can e-mail me at DevPerf@Microsoft.com.

    Regards,

    David Berg
    Microsoft Developer Division
    Performance Engineering Team
    "So what's happening is this - every second you take the pulse of VS, and if at that particular instant in time, it's doing anything that takes longer than 2 ms, then you're counting the entire second as being hung.  I don't think that's really fair."

    The reason is because without the sleep for 1000ms the application would consume too much CPU, which would negatively effect VS's performance even more. So instead of constantly polling for 1000ms, I choose to check at intervals. you can spread out the timing even more, its still sluggish.

    Thinking about it a little more, a better way might be to post a message, then sleep for a second and see if the message was processed.

    I guess the point wasnt really to have perfect profiling code, rather to point out that profiling UI is an easy way to quantify perceived performance. Its important because if a developer loses their train of thought it costs the company money.


Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.