我理解异步方法的重点不在于提高性能,但我发现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内返回。
答案 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);
}
}
}