Freigeben über


SYSK 106: The Cost of Using WindowsPrincipal

Did you know that using WindowsPrincipal.IsInRole is ~40+% slower than doing the same work yourself?  Run the code below and you’ll see …  Don’t take me wrong – I do not suggest you avoid using IsInRole call; after all a single call is so fast on most computers that it is not even measurable using a timer…  It’s just nice to know the cost of doing business J

 

public bool IsInRoleCustom(System.Security.Principal.WindowsIdentity wi, string role)

{

    bool result = false;

    System.Security.Principal.IdentityReference id = new System.Security.Principal.NTAccount(role).Translate(typeof(System.Security.Principal.SecurityIdentifier));

   

    foreach (System.Security.Principal.IdentityReference group in wi.Groups)

    {

        if (group.Value == id.Value)

        {

            result = true;

            break;

        }

    }

    return result;

}

public bool IsInRoleSystem(System.Security.Principal.WindowsIdentity wi, string role)

{

    return new System.Security.Principal.WindowsPrincipal(wi).IsInRole(role);

}

private void Form1_Load(object sender, EventArgs e)

{

    System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent();

   

    string role = "Guests";

    int cnt = 20000;

    long t11, t12, t21, t22;

    t11 = DateTime.Now.Ticks;

    for (int i = 1; i < cnt; i++)

    {

        bool result = IsInRoleCustom(wi, role);

    }

    t12 = DateTime.Now.Ticks;

    t21 = DateTime.Now.Ticks;

    for (int i = 1; i < cnt; i++)

    {

        bool result = IsInRoleSystem(wi, role);

    }

    t22 = DateTime.Now.Ticks;

    System.Diagnostics.Debug.WriteLine((t12-t11).ToString());

    System.Diagnostics.Debug.WriteLine((t22-t21).ToString());

    System.Diagnostics.Debug.WriteLine(((t22 - t21)/TimeSpan.TicksPerMillisecond).ToString());

    System.Diagnostics.Debug.WriteLine(((float) (t22 - t21) / (t12 - t11)).ToString());

}

Comments

  • Anonymous
    April 17, 2006
    The question, then, is Why?  What else is the system call doing that's taking up that extra time?

  • Anonymous
    April 17, 2006
    The comment has been removed

  • Anonymous
    April 17, 2006
    I've been in optimization mode for the past couple weeks, so my viewpoint is definitely skewed.  When I see 40% possible improvement in time, it makes me giddy.  Now that improvement may only end up a couple cycles in the long run, and as we all know, we shouldn't prematurely optimize, but if funcX() returns the same boolean value as funcY() with the same parameters and there are no other side effects that differentiate the two functions, I'd take those extra cycles and apply them elsewhere.

    Is there something else going on in the system code that is overlooked in the custom code?  Some edge case that won't get handled correctly by simple SID comparison?

    Anyway, I just thought it was interesting about the performance difference between system and custom code.  For any very specific task like this, you'd expect the system implementer to have selected the ideal implementation.  When the ideal implementation isn't the fastest, it's interesting to hear the reasons why.

  • Anonymous
    October 12, 2006
    Hi, I could not find Group  in WindowsIdentity (as in your code - wi.Groups). Also I could not find "System.Security.Principal.IdentityReference". In what vesion of .NET is this available? Thanks a lot.

  • Anonymous
    October 12, 2006
    .NET 2.0

  • Anonymous
    January 07, 2008
    You've been kicked (a good thing) - Trackback from DotNetKicks.com