c# task overhead
코드 1
public class TaskTest { public static async Task<int> MultiTask(int i) { if(i == 0) { return 0; } Console.Write(" "); return await MultiTask(--i); } public static async Task<int> SingleTask(int i) { for (int j = 0; j < i; ++j) { Console.Write(" "); } return i; } public static async void Test1() { Console.WriteLine("start"); List<Int64> multi = new List<long>(); List<Int64> single = new List<long>(); for (int i=0; i<1000; ++i) { Stopwatch sw = new Stopwatch(); sw.Reset(); sw.Start(); var ret = await MultiTask(1000); sw.Stop(); multi.Add(sw.ElapsedMilliseconds); //Console.WriteLine("m" + sw.ElapsedMilliseconds.ToString()); sw.Reset(); sw.Start(); ret = await SingleTask(1000); sw.Stop(); single.Add(sw.ElapsedMilliseconds); //Console.WriteLine("s" + sw.ElapsedMilliseconds.ToString()); } Console.WriteLine("m avg:" + multi.Average()); Console.WriteLine("s avg:" + single.Average()); } } |
결과 : |
task를 중첩해서 사용했을 때 overhead가 얼마나 있을것인가에 대한 실험인데
제대로 실험이 된건지 잘 모르겠다.
그래서 동시에 다른 스레드들과 섞어서 실험을 해봤다
코드 2
public class TaskTest { public static async Task<int> MultiTask(int i, int marker) { if(i == 0) { return 0; } Console.Write(marker); return await MultiTask(--i, marker); }
public static async Task<int> MultiTask1(int i, int marker) { for (int j = 0; j < i; ++j) { new Task<int>(() => { Console.Write(marker); return 0; }).Start(); } return 0; } public static async Task<int> SingleTask(int i, int marker) { for (int j = 0; j < i; ++j) { Console.Write(marker); } return i; } public static int SingleTaskR(int i, int marker) { if (i == 0) { return 0; } Console.Write(marker); return SingleTaskR(--i, marker); } public static int SingleTaskNR(int i, int marker) { for (int j = 0; j < i; ++j) { Console.Write(marker); } return i; } public static async void Test1() { Console.WriteLine("start"); List<Int64> multi = new List<long>(); List<Int64> single = new List<long>(); List<Int64> singleR = new List<long>(); List<Int64> singleNR = new List<long>(); for (int i = 0; i < 20; ++i) { var ret2 = MultiTask1(1000, 1); Stopwatch sw = new Stopwatch(); sw.Reset(); sw.Start(); var ret = MultiTask(1000, 2); sw.Stop(); multi.Add(sw.ElapsedMilliseconds); //Console.WriteLine("m" + sw.ElapsedMilliseconds.ToString()); Task.WaitAll(new []{ ret2, ret }, 5000); Thread.Sleep(500); var ret3 = MultiTask1(1000, 3); Stopwatch sw1 = new Stopwatch(); sw1.Reset(); sw1.Start(); var ret4 = SingleTask(1000, 4); sw1.Stop(); single.Add(sw1.ElapsedMilliseconds); //Console.WriteLine("s" + sw.ElapsedMilliseconds.ToString()); Task.WaitAll(new[] { ret3, ret4 }, 5000); Thread.Sleep(500); Stopwatch sw2 = new Stopwatch(); sw2.Reset(); sw2.Start(); SingleTaskR(1000, 5); sw2.Stop(); singleR.Add(sw2.ElapsedMilliseconds);
Stopwatch sw3 = new Stopwatch(); sw3.Reset(); sw3.Start(); SingleTaskR(1000, 6); sw3.Stop(); singleNR.Add(sw3.ElapsedMilliseconds); }
Console.WriteLine("m avg:" + multi.Average()); Console.WriteLine("s avg:" + single.Average()); Console.WriteLine("sR avg:" + singleR.Average()); Console.WriteLine("sNR avg:" + singleNR.Average()); } } |
결과 : m avg:119.1 s avg:92.9 sR avg:45.4 sNR avg:41.1 |
출력결과를 보니 적당히 섞여서 실행 되는거 같다.
task가 중첩이 되면 비용이 더 들기는 한가보다
task 없이 재귀가 안재귀보다 약 10% 느리고
task 사용하고 재귀가 안재귀보다 약 28% 느리다
task를 사용하면 사용하지 않았을때보다 약 225% 느리다