4

我知道异步方法的重点不是提高性能,但我发现 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 毫秒内返回,而 SortedSetRangeByScoreAsync api 调用在 5000 毫秒内返回。

4

1 回答 1

2

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

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

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

10000 个同步调用平均完成 1.41190622 毫秒

10000 个异步调用平均完成 1.43989741 毫秒

测量排序集长度 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);
        }
    }

}
于 2015-01-17T16:58:54.333 回答