背景
扩展了一个task粒度的锁,对比一下不同实现方式的效率
task级别锁的实现(传统)
简单来说,就是在循环等待锁释放
task级别锁的实现(改进版)
充分利用async/await 异步等待逻辑实现高效task锁
两种锁测试对比
可以看见改进方式效率更高
方式 | task数量 | cpu占比 | 耗时(毫秒) |
---|---|---|---|
传统 | 1000 | 0%-1% | 21383 |
传统 | 3000 | 0%-1% | 63586 |
传统 | 30000 | 51%-53% | 1869288 |
改进 | 1000 | 0%-1% | 133 |
改进 | 3000 | 0%-1% | 549 |
改进 | 30000 | 50% | 33792 |
测试环境
测试代码
传统方式测试代码
/// <param name="taskNum">测试task数量</param>
public static void Test10(int taskNum)
{
var taskLock = new TaskLock();
var tasks = new Task[taskNum];
int tatolCount = 0;
var times = new int[10];
var watch = new Stopwatch();
watch.Start();
for (int j = 0; j < taskNum; ++j)
{
int index = j + 1;
tasks[j] = Task.Run(async () =>
{
try
{
for (int i = 0; i < 2; ++i)
{
//超时尽量大1000000
await taskLock.Lock(index, 1000000);
times[index % 10]++;
taskLock.Unlock(index);
}
}
catch (Exception e)
{
Console.WriteLine($"task index= {index}:exception info = {e.Message}");
}
});
}
try
{
Task.WaitAll(tasks, 100000000);
}
catch (Exception e)
{
Console.WriteLine($"exception info = {e.Message}");
}
watch.Stop();
Console.WriteLine($"total={tatolCount},times={Glog.GetLogString(times)},cost={watch.ElapsedMilliseconds}");
}
改进版测试代码
/// <param name="taskNum">测试task数量</param>
public static void Test10(int taskNum)
{
var watch = new Stopwatch();
watch.Start();
var taskLock = new TaskLock();
var tasks = new Task[taskNum];
int tatolCount = 0;
var times = new int[10];
for (int j = 0; j < taskNum; ++j)
{
int index = j + 1;
tasks[j] = Task.Run(async () =>
{
try
{
for (int i = 0; i < 2; ++i)
{
await taskLock.Lock(index);
times[index % 10]++;
taskLock.Unlock(index);
}
}
catch (Exception e)
{
Console.WriteLine($"task index= {index}:exception info = {e.Message},trace={Util.GetLog(e)}");
}
});
}
try
{
Task.WaitAll(tasks, 100000000);
}
catch (Exception e)
{
Console.WriteLine($"exception info = {e.Message}");
}
watch.Stop();
Console.WriteLine($"total={tatolCount},times={Glog.GetLogString(times)},costtime={watch.ElapsedMilliseconds}");
}