none
Microsoft.SqlServer.Types is slowing down a call to Form.ActiveForm by a factor of 100! RRS feed

  • General discussion

  • I am running into a situation where when I load Microsoft.SqlServer.Types my app is running slower.
    To show you what is going on, I've been able to get the smallest app as possible.
    This will do 5000 times Form.ActiveForm and measure it's time.
    It should be much and at first it is less than 0.002 seconds.
    Even the version which is doing a recursive call of itself till 200 deep, says 0.002.

    However, after I've done:

          Microsoft.SqlServer.Types.SqlGeography geography = null;

    which just loads Microsoft.SqlServer.Types.dll, the numbers get a lot higher.
    The method which directly calls Form.ActiveForm about 5000 times says 0.017 sec, but the one
    which does it after 200 recursions then performs it in 0.250 sec, which is more than 100 times slower !

     

    When one runs the app and invokes Test1() and TestDeep() via buttons, the numbers get even worse.

     

    Please help,

     

    Pat

     

     

      public class Form1 : Form

      {

        public Form1()

         {

        }

     

        public void Test1()

        {

          int max = 5000;

     

          System.Diagnostics.Stopwatch sw =

    System.Diagnostics.Stopwatch.StartNew();

          for (int i = 0; i < max; i++)

          {

            Form form = Form.ActiveForm;

          }

     

          sw.Stop();

          double time = sw.ElapsedMilliseconds / 1000.0;

          MessageBox.Show(String.Format("Time: {0}, Average: {1}", time, time / max));

        }

     

        public void TestDeep(int level)

        {

          if (level > 0)

          {

            TestDeep(--level);

          }

          else

          {

            Test1();

          }

        }

     

        public void Test3()

        {

          Microsoft.SqlServer.Types.SqlGeography geography = null;

          MessageBox.Show("Sql Server Types Loaded");

        }

      }

     

     

     

      static class Program

      {

        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        [STAThread]

        static void Main()

        {

          Application.EnableVisualStyles();

          Application.SetCompatibleTextRenderingDefault(false);

     

          Form1 form = new Form1();

          form.Show();

     

          form.Test1();

          form.TestDeep(200);

          form.Test3();

     

          form.Test1();

          form.TestDeep(200);

     

          //Application.Run(new Form1());

        }

      }

    Monday, June 8, 2009 5:55 PM

All replies

  • I had to do some serious digging to find that assembly.  No repro:

    64-bit mode:
    Time: 0.185, Average: 3.7E-05
    Time: 0.714, Average: 0.0001428
    Sql Server Types Loaded
    Time: 0.166, Average: 3.32E-05
    Time: 0.732, Average: 0.0001464

    32-bit mode:
    Time: 0.127, Average: 2.54E-05
    Time: 0.509, Average: 0.0001018
    Sql Server Types Loaded
    Time: 0.087, Average: 1.74E-05
    Time: 0.558, Average: 0.0001116

    Which is entirely expected.  Something else is going on on your machine.

    Hans Passant.
    Monday, June 8, 2009 10:57 PM
    Moderator
  • When I run this from Visual Studio 2008 and have enabled the Visual Studio Hosting process I am getting similar results as you have
    (e.g. it doesn't matter weather Microsoft.SqlServer.Types has been loaded or not).
    But run it without the Visual Studio Hosting Process and the figures are quite different.

    I've tested this on
      QuadCore Q6600 running Vista with SP2
      Dell laptop running Windows XP

    and they both give similar result where after loading Microsoft.SqlServer.Types the call to Forms.ActiveForm has become a lot slower.

    I did some more digging on this and it seems (using Reflector) that the following piece of code is responsible:

            // And deep down it is doing the following, which seems to be the cause of the slow down.
            System.Security.Permissions.UIPermission a = new System.Security.Permissions.UIPermission(System.Security.Permissions.UIPermissionWindow.AllWindows);
            a.Demand();

    So make sure you run this outside Visual Studio or disable the Visual Studio Hosting process.

    BTW: Which version of the Microsoft.SqlServer.Types.dll do you have, mine is:


    // Assembly Microsoft.SqlServer.Types
    , Version 10.0.0.0
    
    [assembly:
     AssemblyVersion
    ("10.0.0.0"
    )]
    [assembly:
     RuntimeCompatibility
    (WrapNonExceptionThrows
    =true
    )]
    [assembly:
     AssemblyFileVersion
    ("10.0.1600.22 ((SQL_PreRelease).080709-1414 )"
    )]
    [assembly:
     AllowPartiallyTrustedCallers
    ]
    [assembly:
     AssemblyInformationalVersion
    ("10.0.1600.22"
    )]
    [assembly:
     CLSCompliant
    (false
    )]
    [assembly:
     SecurityCritical
    ]
    [assembly:
     ComVisible
    (false
    )]
    [assembly:
     AssemblyCompany
    ("Microsoft Corporation"
    )]
    [assembly:
     AssemblyProduct
    ("Microsoft SQL Server"
    )]
    [assembly:
     AssemblyCopyright
    ("Microsoft Corp. All rights reserved."
    )]
    [assembly:
     AssemblyTrademark
    ("Microsoft SQL Server is a registered trademark of Microsoft Corporation."
    )]
    [assembly:
     SecurityPermission
    (SecurityAction
    .RequestMinimum
    , SkipVerification
    =true
    )]
    [assembly:
     SecurityPermission
    (SecurityAction
    .RequestMinimum
    , Execution
    =true
    )]
    [assembly:
     SecurityPermission
    (SecurityAction
    .RequestOptional
    , UnmanagedCode
    =true
    )]
    


    Pat
    Tuesday, June 9, 2009 6:35 AM
  • Dear All,

    I just found out that the case of the bad performing Form.ActiveForm
    is caused by a dll having

         [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)]

    I just created a Dll with the above in the Assembly.cs and when that
    dll is loaded into my process space,
    a call to Form.ActiveForm is a lot slower. Internally this seems be
    caused by:

          System.Security.Permissions.UIPermission a = new System.Security.Permissions.UIPermission(System.Security.Permissions.UIPermissionWindow.AllWindows);
          a.Demand();

    Regards,

    Patrick
    Tuesday, June 9, 2009 12:40 PM
  • Well, that kinda makes sense.  Providing a security context is one of the reasons the Visual Studio hosting process exists.  I would guess that without one, the CLR has to do the hard work itself, reviewing Evidence and what-not.  This is all getting deprecated in .NET 4.0, giving me an opportunity to quickly forget what very little I know about it.
    Hans Passant.
    Tuesday, June 9, 2009 1:04 PM
    Moderator
  • So really, this can't be done anything about?

    Just scrap the dll and try to solve it yourself in another way?
    Tuesday, June 30, 2009 12:00 PM
  • Hans Passant (nobugz), it is just the other way around.
    When you run it from within the Visual Studio Hosting process it is always slow...
    When you run it without the hosting process it is fast when the dll with the attribute is not loaded and
    as soon as the dll with attribute:
      
        [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)]

    is loaded the call to Form.ActiveForm is slow...
    So when one provides a security context, does the visual studio hosting process provide one? I have no idea, the lot is slow.
    Tuesday, June 30, 2009 12:14 PM
  • Anonymous5124851,

    I need the Dll, it contains the lot for very specific Sql Server types like, SqlGeometry and SqlGeography.


    Tuesday, June 30, 2009 12:16 PM
  • Patje, I am in the same boat.

    I would like to find a solution, like applying some Attribute to my assembly, to make the problem go away. But I find it very hard to grasp the concept of these security contexts and permission etcetera, so I am not very succesful here...
    Tuesday, June 30, 2009 12:18 PM
  • Patje,

    Was this the same issue you were reporting to DevExpress.  Did the work-around of setting all the BarManager.Form to point to the main form work for you?  Did you have any unexpected side-effects from the workaround?  We are in the same boat and need a solution.

    Thanks
    Thursday, September 3, 2009 5:37 PM
  • dchristian2112,

    Yes this was the same issue we reported to DevExpress.
    We can't set all BarManager.Form to the main form, for a reason I forgot, but had something to do with Images or the like.
    For now we've put our own IMessageFilter in, being the first, it can intercept any Message and the tell our subclassed BarManager
    (yes we use a subclass of the BarManager) to return the MainForm instead of it's own.

    Cheers,

    Patrick
    Thursday, September 3, 2009 7:21 PM
  • Patrick,

    Thanks for the reply, however I am a little uncertain how to apply your remarks.  I can certainly create a subclass of BarManager and override the Form property, but how does the IMessageFilter come into play?  What message(s) are you handling?  If you have a code snippet or two you could share I would greatly appreciate it.

    Thanks,
    David
    Thursday, September 3, 2009 10:22 PM
  • David,

    Well we are still (or again) having issues with it.
    We now have an application which creates a lot of controls on a devexpress layout.
    When the dll with [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)] is loaded,
    the form is about 3 times slower in loading.

    I checked when the dll is not loaded it loads in 0.08 sec,
    when the dll is loaded it loads in 0.225 sec...

    The  only difference is an empty dll with just only that SecurityPermission in it.
    This is a real pain....as I just can't understand why on earth a dll which is loaded later can affect an already running form,
    while it has no code that can slow it down.

    I also see no way to reset this SecurityPermission....
    My test dll is just empty, in essence I want to use Microsoft.SqlServer.Types.dll which has the same security attribuut.

    Sorry I can't help.

    Patje

    Monday, January 11, 2010 3:35 PM
  • Well since you are an MVP, can you help us out on this.
    Why would an empty dll with a security attribute like:

         [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)]

    make my app slower (approx 3 times slower)...

    Note that I can run my app for as long as I want and it's fast...then I click a button to load my empty dll with the above security attribute
    and the app is 3 times slower....this is nuts!

    Please help or advice...

    Patje


    Monday, January 11, 2010 3:40 PM
  • 1) This thread is pretty old and too long. Formulate your question again, provide a small repro (ideally 10-20 lines of code with the assumption that user has only VS installed) and start a new thread.
    2) Have you tried it on more than 1 machine?
    3) Did you measure it with profiler? Did you compare 2 runs - one which is slow and second which is fast? Where is the difference? Where is the time spent?
    4) Can you reproduce your problem without Microsoft.SqlServer.Types.dll?

    -Karel
    Monday, January 25, 2010 7:47 PM
    Moderator
  • Hi Karel,

    Time is spend in Form.ActiveForm and other p/invoked methods.
    As said earlier it is caused by a dll having the following attribute:
         [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)]
    I actually created a (empty) dll with just that one attribute and it slows down most of the GDI/WinForms methods by at least a factor of 3.
    Now I found that the latest Sql Server download installs a new/different version of Microsoft.SqlServer.Types.dll which doesn't have that attribute in it,
    so the performance issue has gone from that point of view.

    I have also tested this in Visual Studio 2010 Beta 2 with .NET Framework 4 and found that, since the security model has changed,
    the app is no longer slow in that environment either even when I load my own created assembly with the above attribute in it.

    Cheers,

    Patje
    Wednesday, January 27, 2010 7:58 AM
  • So your problem is gone or do you still need help with this one?

    If you need help, please post here a small repro which can be compiled, so people can try it out (question #1 above).

    You did not answer question #2:
    2) Have you tried it on more than 1 machine?

    -Karel
    Wednesday, January 27, 2010 6:41 PM
    Moderator
  • Yes the problem is solved now, don't need any further assistence

    And yes we tried it on different machines.
    - Dell Laptop Windows XP
    - Quad Core Vista machine
    - 64 bit Windows 7

    all the same behaviour
    Thursday, January 28, 2010 7:36 AM
  • Dear All,

    I just found out that the case of the bad performing Form.ActiveForm
    is caused by a dll having

    [assembly: SecurityPermission(SecurityAction.RequestOptional, UnmanagedCode = true)]

    I just created a Dll with the above in the Assembly.cs and when that
    dll is loaded into my process space,
    a call to Form.ActiveForm is a lot slower. Internally this seems be
    caused by:

    System.Security.Permissions.UIPermission a = new System.Security.Permissions.UIPermission(System.Security.Permissions.UIPermissionWindow.AllWindows);
    a.Demand();

    Regards,

    Patrick

    The reason is quite out of my expectation, It's like an expert's answer.
    Tuesday, February 15, 2011 4:45 AM