-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
area-System.ThreadinguntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
Milestone
Description
I did some performance testing for async-await on a completed ValueTask and compared it to a Task.CompletedTask. I see that for Task.CompletedTask it does not matter if I bypass await if I check the Task for IsCompletedSuccessfully, but for ValueTask it has significant performance impact (3x). Is there a missing optimization in the async code generated for async-await when using ValueTask?
BenchmarkDotNet=v0.11.3, OS=Windows 7 SP1 (6.1.7601.0)
Intel Core i5-6300U CPU 2.40GHz (Skylake), 1 CPU, 4 logical and 2 physical cores
Frequency=2437558 Hz, Resolution=410.2466 ns, Timer=TSC
.NET Core SDK=2.2.100
[Host] : .NET Core 2.2.0 (CoreCLR 4.6.27110.04, CoreFX 4.6.27110.04), 64bit RyuJIT
Job-OUSAWM : .NET Core 2.2.0 (CoreCLR 4.6.27110.04, CoreFX 4.6.27110.04), 64bit RyuJIT
WarmupCount=1
Method | Mean | Error | StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
--------------------------------------- |-----------:|----------:|----------:|------------:|------------:|------------:|--------------------:|
ValueTask | 1,031.7 ns | 16.990 ns | 15.892 ns | - | - | - | - |
ValueTaskIfIsCompletedSuccessfully | 291.5 ns | 2.743 ns | 2.291 ns | - | - | - | - |
CompletedTaskIfIsCompletedSuccessfully | 277.7 ns | 5.460 ns | 6.288 ns | - | - | - | - |
CompletedTask | 319.5 ns | 4.782 ns | 3.993 ns | - | - | - | - |
[Benchmark]
public async Task ValueTask()
{
for (int i = 0; i < 100; i++)
await new ValueTask();
}
[Benchmark]
public async Task ValueTaskIfIsCompletedSuccessfully()
{
for (int i = 0; i < 100; i++)
{
var valueTask = new ValueTask();
if (!valueTask.IsCompletedSuccessfully)
await valueTask;
}
}
[Benchmark]
public async Task CompletedTaskIfIsCompletedSuccessfully()
{
for (int i = 0; i < 100; i++)
{
var task = Task.CompletedTask;
if (!task.IsCompletedSuccessfully)
await task;
}
}
[Benchmark]
public async Task CompletedTask()
{
for (int i = 0; i < 100; i++)
await Task.CompletedTask;
}
Metadata
Metadata
Assignees
Labels
area-System.ThreadinguntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner