Improve async performance
See original GitHub issueI have a (non-public) test case that executes two bulk read queries (in a batch); one that returns 31K rows of int,string,int,int
and a second that returns 37K rows of int,int,int,int
. The remote server is MySQL 5.6 on Linux, about 10ms away from my test box.
On full .NET 4.6.2 on Windows 10, the sync codepath uses less than one core and completes in 4s; the async code path uses over 300% CPU and takes 20s wall time.
sync:
real 4.043s
total 1.922s
user 1.438s
sys 0.484s
async:
real 20.840s
total 68.422s
user 47.531s
sys 20.891s
With dotnet, the results are even worse:
sync:
real 4.336s
total 1.953s
user 1.469s
sys 0.484s
async:
real 24.468s
total 85.703s
user 59.219s
sys 26.484s
Some investigation with dotTrace and dotPeek on the full .NET Framework shows that Socket.ReceiveAsync
(used in the async code path) takes 2s of CPU time while Socket.Receive
(which blocks until the data is received) only takes 1.5s. Moreover, Socket.ReceiveAsync
appears to only return false
(i.e., receive completed synchronously) on failure; a successful result always completes asynchronously, meaning that we suffer the penalty of a callback being queued to the threadpool on top of the extra CPU time just to initiate the operation!
Additionally, network bandwidth (shown in Task Manager) is noticeably lower for the async case than the sync case.
We may need to find some way to get the benefits of asynchronous I/O without the overhead of Socket.ReceiveAsync
, perhaps by #163 or by writing custom P/Invoke for the full .NET Framework on Windows.
Issue Analytics
- State:
- Created 7 years ago
- Comments:5 (5 by maintainers)
BufferedByteReader
may be useful here; I’ll plan to take a look later.I’m hacking on it as we speak; I’m using
BufferedByteReader
😄