We created a project that returns the average time taken to complete large number of asynchronous tasks on a single thread and on multiple threads. These tasks are mostly empty and just cause a context break on the same thread using await Task.Yield(). The intention is to evaluate Task Scheduler performance.
We compiled the same code with .Net Native and without it. The results that we found out were pretty amazing. With .Net Native same code has degraded performance of 200% on phone and around 25% on desktop app.
Detailed Results (Lower is better):
On Mobile:
Scheduled 20,000 asynchronous tasks and calculated the time taken. We ran this test 10 times to get the average time taken to perform this task.
Single Thread (in sec):
Managed Code(Without .Net Native compilation)
3.02
.Net Native compiled code
9.06
Multiple Threads (in sec):
Managed Code(Without .Net Native compilation)
0.10
.Net Native compiled code
0.29
On Desktop:
Scheduled 80,000 asynchronous tasks and calculated the time taken. We ran this test 10 times to get the average time taken to perform this task.
Single Thread (in sec):
Managed Code(Without .Net Native compilation)
9.15
.Net Native compiled code
11.394
Multiple Threads (in sec):
Managed Code(Without .Net Native compilation)
0.0937
.Net Native compiled code
0.177
Our app uses asynchronous APIs heavily and has visible performance degradation post .Net Native compilation. These numbers seem to explain the degradation unless we’ve missed something. Has anyone else faced similar issue, if yes, is there a workaround?
Code Snippet:
for (int i = 0; i < count; i++)
{
Task.Run(() => ProcessTaskDesktop());
}
public async void ProcessTaskDesktop()
{
await Task.Yield();
.
.
//logic to do iterations and check code end
.
.
}