C# Async client connection performance vs Sync connection


#1

I used C# benchmark test tool (which comes with C# client library) to make a comparison between the performance of the Async and the Sync client connection, but the results were unexpected! We do expect the Async to perform better or the minimum the same.

Now, to accomplish this test, first I initialized a namespace with 600,000 record, and each record has 1000 INT bin (simulation of my business case), and then I ran the test with 100% Read load, and below is the test parameters with results.

  • Sync (8 threads)
           <=1ms  >1ms  >2ms  >4ms  >8ms  >16ms  >32ms    
  write    0%     0%     0%    0%   0%    0%     0%    
  read     0%     100%   45%   6%   0%    0%     0%   

write(tps=0 timeouts=0 errors=0) read(tps=3613 timeouts=0 errors=0) total(tps=3613 timeouts=0 errors=0)

  • Async (max concurrent connections : 40, generator threads: 1)

               <=1ms  >1ms  >2ms  >4ms  >8ms  >16ms  >32ms    
      write    0%     0%     0%    0%   0%    0%     0%    
      read     0%     100%   98%   86%  71%   10%    0%
    

    write(tps=0 timeouts=0 errors=0) read(tps=2943 timeouts=0 errors=0) total(tps=2943 timeouts=0 errors=0)

As you notice from the results above, the Async is badly performing than the Sync connection

Is this normal? can you please advice, and why this is happening?


#2

Asynchronous socket performance in C# has always fell short of expectations. The SocketAsyncEventArgs model was very easy to implement (relative to java async), but C# limits access to lower-level functions that could be leveraged to increase performance.

For example, java provides access to socket selectors. This selector can be directly instantiated and run over multiple threads concurrently (usually one selector instance per cpu). C# hides direct access to it’s equivalent completion port functionality. The only tuning available is to set the minimum number of completion port threads in the global thread pool:

https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setminthreads(v=vs.110).aspx

C# uses this value as a hint and ultimately adjusts its completion port threads to support what it considers optimal resource usage. To its credit, C# async performance does steadily increase the longer the benchmark is run (while java performance remains constant). My opinion is that this optimization is too slow to adjust and would be better off just letting the user dictate this behavior.

That said, there still are some advantages to C# asynchronous programming:

  1. Asynchronous uses far less threads than synchronous.

  2. Asynchronous utilizes each cpu more efficiently.

  3. While per transaction performance degrades, scalability can possibly increase.

We are open to suggestions on how to increase C# asynchronous performance.