最近我一直致力于一个应用程序,它应该是几个服务之上的薄层,这个应用程序主要是从不同的数据格式到统一格式(很多映射)的映射。我们使用我称之为“linq async”但我想看看我是否可以提高其性能。
我做了一个简单的实验,如下面的
using System;
using System.Collections.Async;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int max = 100;
int[] input = Enumerable.Range(1, max).ToArray();
Work w = new Work();
// senario 1
sw.Restart();
var result1 = input.Select(x => w.LongHoursWork(x)).ToArray();
sw.Stop();
Console.WriteLine($"One Thread: {sw.ElapsedMilliseconds}");
// senario 2
sw.Restart();
var result2 = MainAsync(input, w).GetAwaiter().GetResult();
sw.Stop();
Console.WriteLine($"Linq async: {sw.ElapsedMilliseconds}");
// senario 3
sw.Restart();
var result3 = input.AsParallel().Select(x => w.LongHoursWork(x)).ToArray();
sw.Stop();
Console.WriteLine($"Parallel: {sw.ElapsedMilliseconds}");
// check result
for (int i = 0; i < max; i++)
{
if(result1[i] == result2[i] && result2[i] == result3[i])// && result4.Contains(result1[i]))
continue;
throw new ArgumentNullException();
}
Console.ReadKey();
}
static async Task<string[]> MainAsync(int[] input, Work work)
{
var result = await Task.WhenAll(input.Select(async x => await work.LongHoursWorkAsync(x)));
return result;
}
}
public class Work
{
public string LongHoursWork(int i)
{
for (int ix = 0; ix < 100000; ix++)
{
i += ix;
}
return i.ToString();
}
public async Task<string> LongHoursWorkAsync(int i)
{
return await Task.FromResult(LongHoursWork(i));
}
}
}
//execution result:
//One Thread: 88
//Linq async: 97
//Parallel: 59
// if i change the input array to 600(similar to what i have in production
// environment)
// execution result:
// One Thread: 347
// Linq async: 292
// Parallel: 101
我希望senario2(linq async)应该与senario3(并行)大致相同,因为senario2将创建大量任务并同时执行它们。但是,我的简单实验告诉我错误。 Senario2与senario1或多或少相同。这让我很困惑,我试着读书 stackoverflow中的许多相关问题但无法找到满意的答案。大多数问题都是关于非阻塞UI,而我的应用程序是后端服务。另外我读到关于linq async将提高负载下后端服务的吞吐量,但是从我的实验我不相信。如果单次运行的性能不高,它怎样才能提高负载下的吞吐量?另外我注意到输入数组中的项目越多,我就能从并行执行中获得更好的性能(scenario3)。所以我想在这里提出我的问题。
非常感谢提前。
答案 0 :(得分:0)
async-await
的一般好处不是表现而是响应能力。
当发生阻塞操作(通常是I / O)时,它是关于释放当前线程(客户端UI上的UI线程,ASP.NET上的线程池线程)。
因为每次释放线程时都会有一个上下文切换以及当一个线程被抓取以继续执行时,异步代码会产生一些开销,因此性能较差。
但是因为它促进了对资源的更好利用,整个系统可能会因为响应速度更快而感觉更高效。
当真正的并行性可行时,是的,系统的性能更高。
一般而言,关于性能,您应该始终测量您的特定用例。