0

I have the following method that I want to load test with Task.WhenAll():

static async Task<User> GetUserAsync()
{
    return (await new ApiTester().GetUserAsync());
}

Essentially, I want to call this method 100 times simultaneously and at the end of processing, identify total elapsed time and time per method call. Can you provide the code if you know how to do this? This is probably easy for a Task.WaitAll expert but I've only used this method once for one very specific scenario.

user9393635
  • 1,369
  • 4
  • 13
  • 32
  • Sure, use [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) – Yurii N. Jun 28 '18 at 00:42
  • The question is why? what do you want to figure out. i mean its easy enough to use a `StopWatch` and a list of task, but im not sure what you are proving to your self, this is IO stuff, you loading up completion ports and you will be thrashing context switching and the threadpool while the completion ports kick in and out – TheGeneral Jun 28 '18 at 00:56
  • @TheGeneral the point is to load test the GetUserAsync implementation to validate that it will scale – user9393635 Jun 28 '18 at 01:01
  • 2
    Two problems-- (1) Your test runner probably has the wrong kind of [SynchronizationContext](https://stackoverflow.com/questions/18097471/what-does-synchronizationcontext-do) and (2) performance dynamics are almost always nonlinear, which means you can't get meaningful results by testing only a portion of the system in isolation. You should do your perf test against the full application, running on production-like hardware. – John Wu Jun 28 '18 at 01:44

1 Answers1

2

You should use BenchmarkDotNet. However here is a crude way of achieving what you want.

Your Method

private static async Task<User> GetUserAsync() 
{    
   return await new ApiTester().GetUserAsync(); 
}

Async Timer task

private static async Task<double> GetUserMsAsync()
{
   var sw = new Stopwatch();
   sw.Start();
   var user = await GetUserAsync();
   sw.Stop();

   return sw.Elapsed.TotalMilliseconds;
}

Tester

public static async Task Tester()
{
   var sw = new Stopwatch();

   try
   {
      var tasks = Enumerable.Range(0, 100)
                            .Select(x => GetUserMsAsync())
                            .ToArray();

      sw.Start();

      var results = await Task.WhenAll(tasks);

      foreach (var result in results)
      {
         Console.WriteLine(result);
      }
   }
   finally
   {
      sw.Stop();
      Console.WriteLine($"sw : {sw.Elapsed:c}");
   }
}

Usage

private static void Main(string[] args)
{
   Tester().Wait();  
   Console.ReadKey();
}

Disclaimer, this is not really going to prove much if you don't understand what you are testing and the environment your are testing in. However, I'll assume you do.

halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141