Home > OS >  C# - Stopwatch timers not adding up
C# - Stopwatch timers not adding up

Time:11-05

There's a piece of code I've been fiddling with to see if I can speed it up because it definitely shouldn't take 3.8 to 4.4 seconds to process about 1400 UserPrincipals.

I've used stopwatches to time different pieces of the function when I noticed that the pieces don't add up to the timer measuring the entire function. The gap is relatively dramatic and I can't figure out where it's coming from. I'd appreciate any insight.

The SamAccountName measurement is because I found some info that it can potentially be slow because of how the getter of the property is implemented, for anyone wondering.

Function code:

private static ConcurrentDictionary<string, User> ProcessUsers(List<UserPrincipal> users)
    {
        ConcurrentDictionary<string, User> toReturn = new ConcurrentDictionary<string, User>(4, 2000);
        Regex regex = new Regex(@"^[a-zA-Z]{3}(\d{4})$");         

        Parallel.ForEach(users, user =>
        {
            Stopwatch timerSamAccountName = new Stopwatch();
            Stopwatch timerIfBlock = new Stopwatch();
            Stopwatch timerTotal = new Stopwatch();

            timerTotal.Start();

            timerSamAccountName.Start();
            string guid = user.SamAccountName;
            timerSamAccountName.Stop();
            Console.WriteLine($"SamAccountName done in {timerSamAccountName.Elapsed} for {user.Name}");

            timerIfBlock.Start();
            if (regex.IsMatch(guid))
            {
                User newUser = new User(user.Name, guid.ToUpper(), user.EmailAddress, user); 
                toReturn.TryAdd(newUser.ID, newUser);
            }
            timerIfBlock.Stop();
            Console.WriteLine($"IF block done in {timerIfBlock.Elapsed} for {user.Name}");
            
            timerTotal.Stop();
            Console.WriteLine($"User processed in {timerTotal.Elapsed} for {user.Name}");
        });
        return toReturn;
    }

User class:

internal class User
{
    public string name { get; set; }
    public string ID { get; set; }
    public string email { get; set; }
    public UserPrincipal? activeDirectoryHandle { get; set; }

    public User(string inName = "None", string inID = "None", string inEmail = "None", UserPrincipal? adHandle = null)
    {
        name = inName;
        ID = inID;
        email = inEmail;
        activeDirectoryHandle = adHandle;
    }
}

Example of the discrepancy:

sample

CodePudding user response:

The timers don't add up because you're doing work in places where some of the timers (timerSamAccountName and timerIfBlock) aren't running. Additionally, the work you're doing outside the timers (string interpolation and writing to the console) are the longest-running operations in the whole example. You've pretty much measured how much slower these operations are, in fact.

  • Related