3

Running code in .NET Core to connect to a SQL Server database seems much slower than in the full .NET Framework. Is this the case? Or I am doing something wrong?

I have SQL Server 2017 on my PC and want to run a simple stored procedure like

CREATE PROCEDURE OneRowSelect
AS
BEGIN
    SELECT 1
END
GO

I use SQL Client 4.6.0 to connect to the database, and get the result of this procedure in my code. So I wrote a .Net Standard 2.0 library that provides this code:

private const string connectionString = @"data source=.;initial catalog=TestDB;Integrated Security=SSPI;";
private const string command = @"OneRowSelect";

public static async System.Threading.Tasks.Task Execute()
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        using (SqlCommand cmd = new SqlCommand(command, con)
        {
            CommandType = CommandType.StoredProcedure
        })
        {
            con.Open();
            var data = await cmd.ExecuteReaderAsync();

            while (data.Read())
            {
                var res = data[0];
            }
        }
    }
}

Finally I wrote two projects in .NET Core 2.2 and .NET Framework 4.7.2 and referenced this .NET Standard library in these two projects and log the execution time of Execute function with Stopwatch.

My code in these two projects is:

Stopwatch stopwatch = Stopwatch.StartNew();

for (int i = 0; i < repeat; i++)
    await Runner.Execute();
stopwatch.Stop();

The result was unbelievable. .NET Core is much slower than .NET Framework in my system. The results are:

  • .NET Framework average running time: 2.2ms
  • .NET Core average running time: 36.7ms

Am I wrong or is .NET Core this much slower than the .NET Framework?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
amin mirzaee
  • 109
  • 2
  • 9
  • 1
    Did you call this method just once, or repeatedly? (If you measure a single timing, there are all *kinds* of things that can affect it. Ideally, use Benchmark.NET to do this properly.) Have you tried the same kind of test with a *useful* query/SP rather than a no-op one? – Jon Skeet Apr 20 '19 at 07:09
  • I run this method 100 times and got an average(also I repeat this test multiple time). Yes, I have tested this with exact database that fetch some ids of my table and I have seen some results like this – amin mirzaee Apr 20 '19 at 07:18
  • 1
    It may be worth looking at some potential differences like whether .NET Core is using TCP/IP and .NET Framework is using named pipes. I don't know whether that's the case, but *forcing* them to use the same transport would at least be an interesting start. I very much doubt that this is about the CLR itself. – Jon Skeet Apr 20 '19 at 07:30
  • Can you check, if the performance get's better, if you remove the async calling? Then it might be connected to [this](https://github.com/dotnet/corefx/issues/27769) issue. – Volkmar Rigo Apr 20 '19 at 07:47
  • OK. I have just removed the async calls and test it again. The results of .Net-Framework becomes 4.2 and .Net-Core becomes 18.4 which is also much slower than .Net-Framework – amin mirzaee Apr 20 '19 at 08:07
  • @AminMirzaee How come you are not doing await conn.OpenAsync() and await reader.ReadAsync(). You have a mish-mash of synchronous and async code. – William Xifaras Apr 21 '19 at 22:25
  • @WilliamXifaras You were right. I should have used Async in all of my code, however it wouldn't changed the result after another test – amin mirzaee Apr 22 '19 at 06:44
  • Did you try running a single `Runner.Execute()` before the Stopwatch based benchmark? (maybe there is some internal warm-up code that's slower on first call to improve calls afterwards) – hiiru Apr 23 '19 at 18:40
  • @hiiru I have done what you want and the result didn't changed – amin mirzaee Apr 27 '19 at 13:40

0 Answers0