.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)
2021-05-13 01:29
标签:bsp art view 公司 运行 db2 targe iis 区别 很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语言的异步性能测试(有关异步和同步的问题,请参考客《AIO与BIO接口性能对比》),于是我今天写了一个C#的测试程序。 首先,建一个 ASP.NET MVC WebAPI项目,在默认的控制器 values里面,增加两个方法: 然后,建立一个控制台程序,来测试这个web API: 其实主要是下面几行代码: 注意,你可能需要使用Nuget添加下面这个包: Microsoft.AspNet.WebApi.Client 最后,运行这个测试,结果如下: 本来想尝试测试10000个线程,但报错了。 上面的测试结果,QPS并不高,但由于使用的是IISExpress,不同的Web服务器软件性能不相同,所以还得对比下进程内QPS结果,于是新建一个控制台程序,代码如下: 注意,关键代码只有下面两个方法: 这两个方法跟WebAPI的测试方法代码是一样的,但是调用代码稍微不同: 同步调用: 异步调用: 可见,这里测试的时候,同步和异步调用,客户端代码都是使用的多线程,主要的区别就是异步方法使用了 async/await 语句。 下面是非Web的进程内异步多线程和同步多线程的结果: 结果表示,.NET程序开启10000个原生线程,异步方法的QPS超过了10万,而同步方法只有1000多点,性能差距还是很大的。 总结: 不论是普通程序还是Web程序,使用异步多线程,可以极大的提高系统的吞吐量。 .net异步性能测试(包括ASP.NET MVC WebAPI异步方法) 标签:bsp art view 公司 运行 db2 targe iis 区别 原文地址:http://www.cnblogs.com/bluedoctor/p/7562705.html // GET api/values?sleepTime=10
[HttpGet]
public async Taskstring> ExecuteAIO(int sleepTime)
{
await Task.Delay(sleepTime);
return "Hello world,"+ sleepTime;
}
[HttpGet]
// GET api/values?sleepTime2=10
public string ExecuteBIO(int sleepTime2)
{
System.Threading.Thread.Sleep(sleepTime2);
return "Hello world," + sleepTime2;
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("按任意键开始测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}");
Console.Write("请输入线程数:");
int threadNum = 100;
int.TryParse(Console.ReadLine(), out threadNum);
while (Test(threadNum)) ;
Console.ReadLine();
Console.ReadLine();
}
private static bool Test(int TaskNumber)
{
Console.Write("请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:");
string input = Console.ReadLine();
int SleepTime = 50;
if (!int.TryParse(input, out SleepTime))
return false;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:62219/");
var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;
Console.WriteLine("Result:{0}", result);
//int TaskNumber = 1000;
Console.WriteLine("{0}次 BIO(同步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
Task[] taskArr = new Task[TaskNumber];
for (int i = 0; i )
{
Task task = client.GetStringAsync("api/values?sleepTime2=" + SleepTime);
taskArr[i] = task;
}
Task.WaitAll(taskArr);
sw.Stop();
double useTime1 = sw.Elapsed.TotalSeconds;
Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber/useTime1);
sw.Reset();
Console.WriteLine("{0}次 AIO(异步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);
sw.Start();
for (int i = 0; i )
{
Task task = client.GetStringAsync("api/values?sleepTime=" + SleepTime);
taskArr[i] = task;
}
Task.WaitAll(taskArr);
sw.Stop();
double useTime2 = sw.Elapsed.TotalSeconds;
Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2);
return true;
}
}
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:62219/");
var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;
按任意键开始测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}
请输入线程数:1000
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
Result:"Hello world,10"
1000次 BIO(同步)测试(睡眠10 毫秒):
耗时(秒):1.2860545,QPS: 777.57
1000次 AIO(异步)测试(睡眠10 毫秒):
耗时(秒):0.4895946,QPS: 2042.51
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
Result:"Hello world,100"
1000次 BIO(同步)测试(睡眠100 毫秒):
耗时(秒):8.2769307,QPS: 120.82
1000次 AIO(异步)测试(睡眠100 毫秒):
耗时(秒):0.5435111,QPS: 1839.89
class Program
{
static void Main(string[] args)
{
Console.WriteLine("按任意键开始测试 ");
Console.Write("请输入线程数:");
int threadNum = 100;
int.TryParse(Console.ReadLine(), out threadNum);
while (Test(threadNum)) ;
Console.ReadLine();
Console.ReadLine();
}
private static bool Test(int TaskNumber)
{
Console.Write("请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:");
string input = Console.ReadLine();
int SleepTime = 50;
if (!int.TryParse(input, out SleepTime))
return false;
var result = ExecuteAIO(SleepTime).Result;
Console.WriteLine("Result:{0}", result);
//int TaskNumber = 1000;
Console.WriteLine("{0}次 BIO(同步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
Task[] taskArr = new Task[TaskNumber];
for (int i = 0; i )
{
Task task = Task.Runstring>(()=> ExecuteBIO(SleepTime));
taskArr[i] = task;
}
Task.WaitAll(taskArr);
sw.Stop();
double useTime1 = sw.Elapsed.TotalSeconds;
Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber / useTime1);
sw.Reset();
Console.WriteLine("{0}次 AIO(异步)测试(睡眠{1} 毫秒):", TaskNumber, SleepTime);
sw.Start();
for (int i = 0; i )
{
Task task = ExecuteAIO(SleepTime);
taskArr[i] = task;
}
Task.WaitAll(taskArr);
sw.Stop();
double useTime2 = sw.Elapsed.TotalSeconds;
Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2);
return true;
}
public static async Taskstring> ExecuteAIO(int sleepTime)
{
await Task.Delay(sleepTime);
return "Hello world," + sleepTime;
}
public static string ExecuteBIO(int sleepTime2)
{
System.Threading.Thread.Sleep(sleepTime2);
//不能在非异步方法里面使用 Task.Delay,否则可能死锁
//Task.Delay(sleepTime2).Wait();
return "Hello world," + sleepTime2;
}
}
public static async Taskstring> ExecuteAIO(int sleepTime)
{
await Task.Delay(sleepTime);
return "Hello world," + sleepTime;
}
public static string ExecuteBIO(int sleepTime2)
{
System.Threading.Thread.Sleep(sleepTime2);
//不能在非异步方法里面使用 Task.Delay,否则可能死锁
//Task.Delay(sleepTime2).Wait();
return "Hello world," + sleepTime2;
}
Task[] taskArr = new Task[TaskNumber];
for (int i = 0; i )
{
Task task = Task.Runstring>(()=> ExecuteBIO(SleepTime));
taskArr[i] = task;
}
Task.WaitAll(taskArr);
for (int i = 0; i )
{
Task task = ExecuteAIO(SleepTime);
taskArr[i] = task;
}
Task.WaitAll(taskArr);
请输入线程数:1000
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
Result:Hello world,10
1000次 BIO(同步)测试(睡眠10 毫秒):
耗时(秒):1.3031966,QPS: 767.34
1000次 AIO(异步)测试(睡眠10 毫秒):
耗时(秒):0.026441,QPS: 37820.05
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
Result:Hello world,100
1000次 BIO(同步)测试(睡眠100 毫秒):
耗时(秒):9.8502858,QPS: 101.52
1000次 AIO(异步)测试(睡眠100 毫秒):
耗时(秒):0.1149469,QPS: 8699.67
请输入线程数:10000
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:10
Result:Hello world,10
10000次 BIO(同步)测试(睡眠10 毫秒):
耗时(秒):7.7966125,QPS: 1282.61
10000次 AIO(异步)测试(睡眠10 毫秒):
耗时(秒):0.083922,QPS: 119158.27
请输入此API方法的睡眠时间(毫秒),输入非数字内容退出:100
Result:Hello world,100
10000次 BIO(同步)测试(睡眠100 毫秒):
耗时(秒):34.3646036,QPS: 291.00
10000次 AIO(异步)测试(睡眠100 毫秒):
耗时(秒):0.1721833,QPS: 58077.64
上一篇:ActiveMQ在C#中的应用
下一篇:C#窗体工具习题
文章标题:.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)
文章链接:http://soscw.com/essay/84945.html