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…

3 comments on “Parallel vs. Async Email performance

  1. The difference isnt huge. Wonder what performance would be like if you bumped it up to a couple of hundred emails or if you used something like BCC instead.

  2. Yeh i wanted to try sending more but i spammed gmail enough for 1 day might try it again and bump it up and possibly even try it with an attachment or something.

  3. Mattias W says:

    I am not really sure what you are trying to test. I have only used parallel and async in F# and there might be that I misunderstand how they work in C#. For me, they have completely different usage.

    I use parallel to handle CPU intensive work, and there is no point in have more parallel processes than number of hyperthreads on the CPU, so typical 4 or 8.

    Async is not used for CPU-intensive work, it is instead used for calls with a large latency, for example sending emails. So, if I would like to send 20 emails, I can have 20 outstanding async-request, so the time should more or less be the same for 1, 8, 15 or 20 emails. Since you do not get the result, I would just say that your email server blocks all you do to a single queue. I would redo the samples with something different, but similar, for example downloading 1000 web pages. There you should see a huge difference once you pass the number of cores/HT.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>