StackExchange.Redis异步调用比同步调用慢

时间:2015-01-16 09:54:50

标签: c# async-await stackexchange.redis

我理解异步方法的重点不在于提高性能,但我发现StackExchange.Redis上的异步方法比同步方法花费的时间更长

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;
}

异步调用大约需要5000毫秒,而非异步调用大约需要30毫秒。我的redis托管在azure上。有什么想法吗?

修改:我在这里谈论单一请求。 SortedSetRangeByScore api调用在30 ms内返回,而SortedSetRangeByScoreAsync api调用在5000 ms内返回。

1 个答案:

答案 0 :(得分:2)

想知道如何衡量比较的延迟?我尝试使用以下代码进行测量,SE.Redis为异步vs同步所花费的时间非常接近。我希望这会有所帮助。

我的客户端代码在Azure Iaas VM上运行,并连接到同一区域中的Azure Redis缓存。

测量同步与异步的排序集长度10000,迭代10000

10000次同步通话平均完成1.41190622 ms

10000个异步调用平均完成1.43989741 ms

测量同步与异步的排序集长度100000,迭代1

1个同步调用平均完成0.9513毫秒

1个异步调用平均完成1.1436毫秒

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);
        }
    }

}