Kaladin
Kaladin

Reputation: 803

StackExchange.Redis Async calls slower than sync calls

I understand that the point of asynchronous methods are not to improve performance but I am finding that the asynchronous methods on the StackExchange.Redis is taking alot longer than the sync methods.

public static async Task<bool> GetScoresFromSetAsync(int score, string name)
{
  string redisConnection = ConfigurationManager.AppSettings["RedisAccount"].ToString();
  ConnectionMultiplexer connection = ConnectionMultiplexer.Connect(redisConnection);
  IDatabase _cache = connection.GetDatabase();

  List<string> scores = new List<string>();

  var resultAsync = await _cache.SortedSetRangeByScoreAsync(name, score, score);
  var result = _cache.SortedSetRangeByScore(name score, score);
  return true;
}

The async call is taking about 5000 ms while the non async one is taking about 30ms on average. My redis is hosted on azure. Any thoughts?

Edit: I am talking about a single request here. The SortedSetRangeByScore api call is returning within 30 ms while the SortedSetRangeByScoreAsync api call is returning within 5000 ms.

Upvotes: 5

Views: 10110

Answers (1)

Deepak
Deepak

Reputation: 2233

Wondering how are you measuring the latency to compare? I tried measuring it with the following code and the time taken by SE.Redis for async vs sync came out to be pretty close. I hope this helps.

My client code is running on a Azure Iaas VM and connecting to a Azure Redis Cache in the same region.

Measuring sync vs async for sorted set length 10000, iterations 10000

10000 sync calls completed in average 1.41190622 ms

10000 async calls completed in average 1.43989741 ms

Measuring sync vs async for sorted set length 100000, iterations 1

1 sync calls completed in average 0.9513 ms

1 async calls completed in average 1.1436 ms

using StackExchange.Redis;

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Threading;

using System.Threading.Tasks;

namespace RedisLatency

{

    class Program

    {

        private const string host = "myazurecache.redis.cache.windows.net";

        private const string password = "password";

        private static int sortedsetlength;

        private static int iterations;

        private static IDatabase _cache;

        static void Main(string[] args)

        {

            sortedsetlength = Int32.Parse(args[0]);

            iterations = Int32.Parse(args[1]);

            CreateMultiplexer(host,password);

            PopulateTestData();

            RunTestSync();

            RunTestAsync();

        }

        private static void CreateMultiplexer(string host, string password)

        {

            Console.WriteLine("Measuring sync vs async for sorted set length {0}, iteration {1}", sortedsetlength,iterations);

            ConfigurationOptions configoptions = new ConfigurationOptions();

            configoptions.EndPoints.Add(host);

            configoptions.Password = password;

            configoptions.Ssl = true;

            ConnectionMultiplexer connection =   ConnectionMultiplexer.Connect(configoptions);

            _cache = connection.GetDatabase();
        }

        private static void PopulateTestData()

        {

          for (int i = 0; i < sortedsetlength; i++)

            {
                _cache.SortedSetAdd("testsorted", "user" + i, i);
            }
        }

        static void RunTestSync()

        {

            for (int warmup = 0; warmup < 100; warmup++)

            {

                MeasureSync();

            }

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < iterations;i++ )

            {
                MeasureSync();
            }

            sw.Stop();

            Console.WriteLine("{0} sync calls completed in average {1} ms", iterations, sw.Elapsed.TotalMilliseconds/iterations);
        }

        async static void RunTestAsync()

        {

            //warm up

            for (int warmup = 0; warmup < 100; warmup++)
            {
                MeasureAsync().Wait();    
            }

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < iterations; i++)

            {

                MeasureAsync().Wait();

            }

            sw.Stop();

            Console.WriteLine("{0} async calls completed in average {1} ms", iterations, sw.Elapsed.TotalMilliseconds/iterations);

        }

        static public void MeasureSync()

        {

            var result = _cache.SortedSetRangeByScore("testset", 1.0, sortedsetlength / 1.0);

        }

        async static public Task MeasureAsync()
        {
            var result = await _cache.SortedSetRangeByScoreAsync("testset", 1.0, sortedsetlength / 1.0);
        }
    }

}

Upvotes: 2

Related Questions