views:

88

answers:

3

I am trying to write a utility to see if a user has logged in to windows since a date that I have stored in a database.

private void bwFindDates_DoWork(object sender, DoWorkEventArgs e)
{
    UserPrincipal u = new UserPrincipal(context);
    u.SamAccountName = "WebLogin*";
    PrincipalSearcher ps = new PrincipalSearcher(u);
    var result = ps.FindAll();
    foreach (WebAccess.WebLoginUsersRow usr in webAccess.WebLoginUsers)
    {
        UserPrincipal b = (UserPrincipal)result.
            Single((a) => a.SamAccountName == usr.WEBUSER);
        if (b.LastLogon.HasValue)
        {
            if (b.LastLogon.Value < usr.MODIFYDATE)
                usr.LastLogin = "Never";
            else
                usr.LastLogin = b.LastLogon.Value.ToShortDateString();
        }
        else
        {
            usr.LastLogin = "Never";
        }
    }
}

However the performance is very slow. The user list I am pulling from has about 150 Windows users, so when I hit the line UserPrincipal b = (UserPrincipal)result.Single((a) => a.SamAccountName == usr.CONVUSER); it takes 10 to 15 seconds for it to complete per user (stepping through i can see it is doing the step a.SamAccountName == usr.CONVUSE is run for every person so the worst case is running O(n^2) times)

Any recommendations on ways to improve my efficiency?

+2  A: 
LBushkin
+2  A: 

I would suggest:

var result = ps.FindAll().ToList();

Since PrincipalSearchResult doesn't cache like other things, this will bring you down near an O(n) performance level.

Nick Craver
+2  A: 
var userMap = result.ToDictionary(u => u.SamAccountName);

foreach (WebAccess.WebLoginUsersRow usr in webAccess.WebLoginUsers)
{
    UserPrincipal b = userMap[usr.WEBUSER];

    // ...
}
mquander
I like this one. +1
Randolpho
Note that I used `ToDictionary` because your use of `Single` implies that you expect exactly one match for every `WebLoginUsersRow`. Adjust as necessary.
mquander
Thanks. about 15 secconds for the first entry and instantaneous for the rest.
Scott Chamberlain