여기에 메서드 반환 작업에 대한 벤치 마크가 있지만 후드 아래에서 동기화되어 실행됩니다. UsingAsyncModifier보다 UsingTaskFromResult 10 배 빠른"동기화 된"비동기 메서드의 오버 헤드는 무엇입니까?
Repeat 10000 times.
UsingAsyncModifier: 00:00:00.1043980
UsingTaskCompletionSource: 00:00:00.0095270
UsingTaskFromResult: 00:00:00.0089460
반복 10,000 번 :
class MainClass
{
public static async Task<int> UsingAsyncModifier()
{
return 10;
}
public static Task<int> UsingTaskCompletionSource()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tcs.SetResult(10);
return tcs.Task;
}
public static Task<int> UsingTaskFromResult()
{
return Task.FromResult(10);
}
public static void Main(string[] args)
{
DateTime t = DateTime.Now;
const int repeat = 10000; // Results volatile while repeat grows.
Console.WriteLine("Repeat {0} times.", repeat);
int j = 0;
for (int i = 0; i < repeat; i++)
{
j += UsingAsyncModifier().Result;
}
Console.WriteLine("UsingAsyncModifier: {0}", DateTime.Now - t);
t = DateTime.Now;
for (int i = 0; i < repeat; i++)
{
j += UsingTaskCompletionSource().Result;
}
Console.WriteLine("UsingTaskCompletionSource: {0}", DateTime.Now - t);
t = DateTime.Now;
for (int i = 0; i < repeat; i++)
{
j += UsingTaskFromResult().Result;
}
Console.WriteLine("UsingTaskFromResult: {0}", DateTime.Now - t);
}
}
출력 (10,000/100,000/1000,000 번 반복).
Repeat 100000 times.
UsingAsyncModifier: 00:00:00.1676000
UsingTaskCompletionSource: 00:00:00.0872020
UsingTaskFromResult: 00:00:00.0870180
반복을 10 번, UsingTaskFromResult 배보다 빠른 UsingAsyncModifier.
Repeat 1000000 times.
UsingAsyncModifier: 00:00:00.8458490
UsingTaskCompletionSource: 00:00:00.8870980
UsingTaskFromResult: 00:00:00.9027320
반복을 백만 번, UsingAsyncModifier UsingTaskFromResult보다 약간 더 빠르게.
내 생각에 async
수정자가 Task.FromResult()
과 같은 완료된 작업을 만들었습니다. 그러나 벤치 마크는 내 생각을 증명하지 못합니다. 왜? I는 DateTime
를 사용하여 유사한 결과를 볼 동안
매우 높은 반복에있는 시간이 거의 동일했다 있다는 사실 가능성이 낮은 반복의 차이는 소음, GC를 기반으로하고 있다는 것을 의미 그것을 읽어 비동기 방식의 경우에는 해당되지 않습니다 컬렉션, 컨텍스트 스위치 및 기타 오류를 벤치마킹 프레임 워크와 비교합니다. 또한'DateTime.Now'는 short라는 시간을 측정 할만큼 정밀도가 충분하지 않습니다. * 빠른 속도로 실행되는 벤치마킹 코드 조각은 * 정말 * 어렵습니다. 본질적으로, 당신의 테스트는 실제로 의미있는 것을 말하는 것이 아닙니다. 오류 범위가 너무 커서 결과를 효과적으로 의미가 없게됩니다. – Servy
첫 번째 방법이 너무 간단하여 컴파일러가 최적화 할 수는 없습니다. 동기식으로 실행될 수도 있습니다 (백그라운드 작업이 너무 빨리 실행되어 비동기 요청이 완료되기 전에 완료된 것으로 호출자에게 표시 될 수 있음을 알고 있습니다). @Servy가 시사 하듯이 이러한 조건에서 테스트가 실제로 의미가있는 것은 아닙니다. –
@DanPuzey,'async'-ed 메소드없이'await'가 동 기적으로 실행됩니다. 반환 된 결과를 래핑하는 작업을 반환하지 않고는 실행할 수 없습니다.나는 '비동기 (async)'를 사용하여 ppl이 내 머리를 부러 뜨리지 않고 내가 쓴 것을 정확하게 이해했다. 더 길게 덜 애매하게 쓰는 법 –