DK Development

The random output of a Windows developer.

DK Development

The random output of a Windows developer.




Parallel vs. Async Email performance

Lately i have been doing some work with sending emails and I have chosen to use some of .NET4.0’s Parallel processing and the FluentEmail library.

I then got thinking about the Performance differences between using Parallel against Asynchronous so I decided to run some tests. Based of the C# Micro Performance Testing Class blog post I have written a simple app for testing this.

Firstly I created my base class for the performance tests, this will later be inherited by by different testers.

Pretty basic, methods to start and finish that set the stopwatch and the finished bool…

public abstract class PerformanceTester
{
    public TimeSpan TotalTime { get; private set; }
    public TimeSpan AverageTime { get; private set; }
    private Stopwatch _stopwatch;
    public int Iterations { get; private set; }
    public bool Finished { get; private set; }

    public PerformanceTester()
    {
        Finished = false;
    }
    public virtual void Run(int iterations)
    {
        Iterations = iterations;
        _stopwatch = Stopwatch.StartNew();
    }
    public void Finish()
    {
        _stopwatch.Stop();
        AverageTime = new TimeSpan(_stopwatch.Elapsed.Ticks / Iterations);
        TotalTime = _stopwatch.Elapsed;
        Finished = true;
    }
}

Now that we have the stone to build off we can create the classes for the tests we went to perform, in this case 1 for Async and 1 for Parallel (below) these 2 classes then just override the Run method and call Finish when its done. However the async class differs slightly as it has to wait for the async callback.

public class ParallelEmails : PerformanceTester
{
    public override void Run(int iterations)
    {
        base.Run(iterations);
        //do stuff here
        Parallel.For(0, iterations, i =>
            {
                //send emails
                Email.From(Settings.FromAddress)
                    .To(Settings.ToAddress)
                    .Subject(Settings.Subject + "P" + i)
                    .Body(Settings.Body)
                    .UsingClient(new SmtpClient(Settings.HostAddress))
                    .Send();
            });
        //all done
        base.Finish();
    }
}
public class AsyncEmails : PerformanceTester
{
    private int _currentIteration;

    public override void Run(int iterations)
    {
        base.Run(iterations);
        //do stuff here
        for (int i = 0; i < iterations; i++)
        {
            Email.From(Settings.FromAddress)
                        .To(Settings.ToAddress)
                        .Subject(Settings.Subject + "A" + i)
                        .Body(Settings.Body)
                        .UsingClient(new SmtpClient(Settings.HostAddress))
                        .SendAsync(emailCallback);
        }
    }
    private void emailCallback(object sender, EventArgs e)
    {
        _currentIteration = _currentIteration + 1;
        if (_currentIteration == Iterations) Finish();
    }
}

Now for some results, now I know the performance will differ depending on PC hardware so I'm testing this on 2 different PCs the first has a Core 2 Duo E6400 @ 2.13GHz and the 2nd has a Core 2 Quad Q6600 @ 2.4GHz.

Table represents my results of the tests (in milliseconds)

Emails Sent Parallel (Dual Core) Parallel (Quad Core) Async
(Dual Core)
Async
(Quad Core)
1 6019 5716 6107 7039
8 26642 39571 34291 25638
15 59282 46897 58849 47730
20 70977 67488 62120 79164

Just a note, these tests were run from the 2 PCs on the same network with the same internet connection connecting to gmails smtp server. Of course there are other factors that would affect performance of these 2 methods but this is just to get an idea of the differences.

Read into that as much as you want but the main thing i got from it is parallel processing is better when you have more cores (which isn't really anything new at all). Good to see the difference in results though.

DK out…

blog comments powered by Disqus