Nyg*_*rds 5 c# benchmarking asynchronous entity-framework asp.net-core
我正在尝试使用 SQL Server Express 和 EF Core 3.1.3 来衡量 ASP.NET Core 3.1 中异步与同步的性能,并且有两个完全相同的函数,除了一个是异步的,一个是同步的:
[HttpGet("search/description/{searchString}")]
public async Task<ActionResult<IEnumerable<Products>>> SearchForProductsDescription(String searchString) {
return await _context.Products.Where(p => p.Description == searchString).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
以及同步版本:
return _context.Products.Where(p => p.Description == searchString).ToList();
Run Code Online (Sandbox Code Playgroud)
我使用 jmeter 作为基准工具,同步函数比异步函数更快(正如预期的那样),但是当我增加 jmeter 中的线程数以使平均响应时间为 500ms< 时,同步代码仍然更快。我尝试过在数据库中使用 1000 行和 20000 行,但它仍然更快。我试图找到一种场景,其中异步函数比同步函数更快,但我遇到了麻烦,是否有什么我出错或误解的地方?
我试图找到一种场景,其中异步函数比同步函数更快,但我遇到了麻烦,是否有什么我出错或误解的地方?
是的。异步代码不应该更快。它应该需要更少的线程。如果有 10000 个并发请求,您可能会在同步进程中看到资源(内存、句柄、线程、CPU)耗尽。但在此之前你的数据库就会崩溃。
在 EF 中,异步数据访问并不是为了提高数据访问本身的性能,而是为了符合更喜欢异步 IO 的应用程序框架的要求,例如具有单个 UI 线程的桌面应用程序或使用 ASP.NET Core 的 Web 应用程序。
EF 中的异步有时也可用于并行发送多个查询或在等待长时间运行的数据库操作时运行一些其他代码。
这是一个综合演示,对于大量并发调用,当线程池小于并发请求数时,async 可以快得多。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncDemo
{
class Program
{
static async Task DoStuffAsync()
{
await Task.Delay(20);
}
static void DoStuffSync()
{
Thread.Sleep(20);
}
static void Main(string[] args)
{
var sw = new Stopwatch();
List<Task> tasks;
var iterations = 1000 * 5;
while (true)
{
sw.Restart();
tasks = new List<Task>();
for (int i = 0; i < iterations; i++)
{
tasks.Add(Task.Run(() => DoStuffSync()));
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine($"{iterations} sync calls {sw.ElapsedMilliseconds}ms {Process.GetCurrentProcess().Threads.Count} threads");
tasks = new List<Task>();
sw.Restart();
for (int i = 0; i < iterations; i++)
{
tasks.Add(DoStuffAsync());
}
Task.WaitAll(tasks.ToArray());
Console.WriteLine($"{iterations} async calls {sw.ElapsedMilliseconds}ms {Process.GetCurrentProcess().Threads.Count} threads");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出
5000 sync calls 5546ms 35 threads
5000 async calls 29ms 35 threads
5000 sync calls 3951ms 51 threads
5000 async calls 38ms 51 threads
5000 sync calls 3481ms 52 threads
5000 async calls 29ms 52 threads
5000 sync calls 3320ms 53 threads
5000 async calls 34ms 53 threads
5000 sync calls 3259ms 53 threads
5000 async calls 32ms 53 threads
5000 sync calls 3253ms 53 threads
5000 async calls 33ms 53 threads
5000 sync calls 3321ms 53 threads
5000 async calls 31ms 53 threads
5000 sync calls 3275ms 53 threads
5000 async calls 33ms 53 threads
5000 sync calls 3259ms 51 threads
5000 async calls 28ms 51 threads
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7107 次 |
| 最近记录: |