AsyncEventingBasicConsumer slower than EventingBasicConsumer

1,219 views
Skip to first unread message

Noel McGrath

unread,
Jun 12, 2019, 8:59:17 AM6/12/19
to rabbitmq-users
I have 2 examples one using EventingBasicConsumer and the other using AsyncEventingBasicConsumer
When I run this the AsyncEventingBasicConsumer is slower to complete.
I would expect it to be faster as threads available to do work when IO going on.
Am I doing something wrong or is it a misunderstanding from me?

Using  EventingBasicConsumer:

class Program
{
static void Main(string[] args)
{
var factory = new ConnectionFactory()
{
//DispatchConsumersAsync = true,
AutomaticRecoveryEnabled = true,
Password = "n",
Port = 5672,
RequestedConnectionTimeout = 3000,
RequestedHeartbeat = 10,
TopologyRecoveryEnabled = true,
UseBackgroundThreadsForIO = false,
UserName = "n",
VirtualHost = "/"
};

var _list = new List<string>() { "trdevmq01b.ccs.local", "trdevmq01b.ccs.local" };
using (var connection = factory.CreateConnection(_list, "test"))
using (var channel = connection.CreateModel())
{
// create queue if not already there
channel.QueueDeclare("testqueue", true, false, false, null);

// set up consumer
var consumer = new EventingBasicConsumer(channel);
consumer.Received += Consumer_Received;
channel.BasicConsume("testqueue", true, consumer);

// publish
var props = channel.CreateBasicProperties();
for (int i = 0; i < 5000; i++)
{
Thread.Sleep(1);
var msgBytes = Encoding.UTF8.GetBytes("Message " + i);
channel.BasicPublish("", "testqueue", props, msgBytes);
Console.WriteLine("Publish " + i);
}

Console.ReadLine();
}
}


private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
{
var body = e.Body;
var content = Encoding.UTF8.GetString(body);
Thread.Sleep(1);
Console.WriteLine("Finished handling " + content);
}
}


Using  AsyncEventingBasicConsumer:

class Program
{
static void Main(string[] args)
{
var factory = new ConnectionFactory()
{
DispatchConsumersAsync = true,
AutomaticRecoveryEnabled = true,
Password = "n",
Port = 5672,
RequestedConnectionTimeout = 3000,
RequestedHeartbeat = 10,
TopologyRecoveryEnabled = true,
UseBackgroundThreadsForIO = false,
UserName = "n",
VirtualHost = "/"
};

var _list = new List<string>() { "trdevmq01b.ccs.local", "trdevmq01b.ccs.local" };
using (var connection = factory.CreateConnection(_list, "test"))
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("testqueue", true, false, false, null);

// set up consumer
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += Consumer_Received;
channel.BasicConsume("testqueue", true, consumer);

// publish
var props = channel.CreateBasicProperties();
for (int i = 0; i < 5000; i++)
{
Thread.Sleep(1);
var msgBytes = Encoding.UTF8.GetBytes("Message " + i);
channel.BasicPublish("", "testqueue", props, msgBytes);
Console.WriteLine("Publish " + i);
}

Console.ReadLine();
}
}


private static async Task Consumer_Received(object sender, BasicDeliverEventArgs e)
{
var body = e.Body;
var content = Encoding.UTF8.GetString(body);
await Task.Delay(1);
Console.WriteLine("Finished handling " + content);
}
}

Karl Nilsson

unread,
Jun 12, 2019, 9:32:55 AM6/12/19
to rabbitmq-users
You haven't given us any idea of how much slower it is but generally async is not about raw speed and is in no way guaranteed to be faster than a synchronous implementation.

Cheers
Karl

--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rabbitmq-users/5aa1f975-c1bc-428d-97b2-edd572b8ff33%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Karl Nilsson

Noel McGrath

unread,
Jun 12, 2019, 10:28:38 AM6/12/19
to rabbitmq-users
Time taken in seconds for message to be completed in Consumer_Received
AsyncEventingBasicConsumer  90 secs
    EventingBasicConsumer           12 secs

Noel McGrath

unread,
Jun 12, 2019, 10:31:12 AM6/12/19
to rabbitmq-users

I did not expect this difference and thought AsyncEventingBasicConsumer  would be faster as while it was waiting for Task.Delay to complete it would be able to do other work.

Luke Bakken

unread,
Jun 12, 2019, 2:24:22 PM6/12/19
to rabbitmq-users
Hi Noel,

The .NET client pre-dates async / await and as such isn't "async all the way down". I suspect that if you looked at performance counters for your test application you would see a very high number of thread switches in your async version.

There may be improvements that could be made to speed up the Async* versions of the current codebase but that analysis and work hasn't been prioritized. The code is open-source so if you have the inclination and time to figure out why such a large difference in performance exists we would be very interested in receiving improvements via pull requests.

Thanks -
Luke

Noel McGrath

unread,
Jun 13, 2019, 3:13:30 AM6/13/19
to rabbitmq-users
Thanks Luke,
Yes I do see a number of threads in use. I presume this switching is causing the delay, didn't realise it would cost the time difference though
Reply all
Reply to author
Forward
0 new messages