Почему эти задачи выполняются быстрее в IIS Express, чем в консольном приложении? - PullRequest
3 голосов
/ 17 января 2020

У меня есть несколько задач, которые выполняются значительно медленнее при запуске в консольном приложении по сравнению с ASP. NET приложением на IIS express.

IIS Express take около 6 секунд, консольное приложение занимает около 12 секунд. Оба запускают сборку релиза.

Одинаковая версия. NET v4.7.1, CLR - 4.0.30319. Такое же оборудование. Тот же код

Код, который выполняет каждая задача, предназначен только для работы процессора, без ввода-вывода. Я запустил код с помощью профилировщика и не вижу особых различий в сборке мусора или какой-либо другой отдельной ветки - только то, что на ASP .NET / IIS Express общий объем работы занимает половину времени.

Если работа выполняется без распараллеливания, расхождение также намного меньше, хотя все еще существует.

Почему я измеряю различия в производительности между запуском одного и того же кода в консольном приложении и в Интернете? приложение, работающее на IIS Express - и как получить ту же производительность в моем тесте консольного приложения / xunit, что и в IIS Express, поэтому я могу надежно и легко измерить производительность за пределами IIS Express.

А вот некоторый код, чтобы продемонстрировать, о чем я спорю ...

Я знаю, что сравнительный анализ можно было бы сделать более тщательно, но он довольно последовательно показывает те же результаты - и с гораздо большим итерации.

Несколько тестов xunit, запущенных с xunit 1.9.2. Тот же код, что и консольное приложение, демонстрирует те же результаты:

void Work()
{
    // The work code is essentially doing something like this, but I demonstrate the exact same
    // results if this method is just a Thread.Sleep(). 

    var list = new Dictionary<string, object>();

    for (int i = 0; i < 100000; i++)
    {
        list.Add(Guid.NewGuid().ToString(), i);
    }
}

[Fact]
public void AspNetVsXUnitTest_TPL()
{
    void Run()
    {
        Task.WaitAll(Enumerable.Range(0, 250)
            .Select(x => Task.Run(Work))
            .ToArray());
    }

    // warmup
    Run();

    var sw = Stopwatch.StartNew();
    var runs = 3;
    for (int i = 0; i < runs; i++)
    {
        Run();
    }
    sw.Stop();

    Console.WriteLine($"Average over {runs} runs: {sw.Elapsed.TotalMilliseconds / runs} ms");

    // Average over 3 runs: 7391,3071 ms
}

[Fact]
public void AspNetVsXUnitTest_Parallel()
{
    void Run()
    {
        Parallel.ForEach(Enumerable.Range(0, 250), x => Work());
    }

    // warmup
    Run();

    var sw = Stopwatch.StartNew();
    var runs = 3;
    for (int i = 0; i < runs; i++)
    {
        Run();
    }
    sw.Stop();

    Console.WriteLine($"Average over {runs} runs: {sw.Elapsed.TotalMilliseconds / runs} ms"); 

    // Average over 3 runs: 7779,8868 ms
}

Затем выполняются действия ASP. NET контроллера WebApi:

void Work()
{
    var list = new Dictionary<string, object>();

    for (int i = 0; i < 100000; i++)
    {
        list.Add(Guid.NewGuid().ToString(), i);
    }
}

[HttpGet]
[Route("tpl")]
public void AspNetVsXUnitTest_TPL()
{
    void Run()
    {
        Task.WaitAll(Enumerable.Range(0, 250)
            .Select(x => Task.Run(Work))
            .ToArray());
    }

    // warmup
    Run();

    var sw = Stopwatch.StartNew();
    var runs = 3;
    for (int i = 0; i < runs; i++)
    {
        Run();
    }
    sw.Stop();

    Debug.WriteLine($"Average over {runs} runs: {sw.Elapsed.TotalMilliseconds / runs} ms");

    // Average over 3 runs: 3950,57063333333 ms
}

[HttpGet]
[Route("parallel")]
public void AspNetVsXUnitTest_Parallel()
{
    void Run()
    {
        Parallel.ForEach(Enumerable.Range(0, 250), x => Work());
    }

    // warmup
    Run();

    var sw = Stopwatch.StartNew();
    var runs = 3;
    for (int i = 0; i < runs; i++)
    {
        Run();
    }
    sw.Stop();

    Debug.WriteLine($"Average over {runs} runs: {sw.Elapsed.TotalMilliseconds / runs} ms");

    // Average over 3 runs: 4135,25496666667 ms
}

Теперь, почему выполняется это кусок кода намного быстрее при работе на IIS Express по сравнению с работой в качестве консольного приложения или в модуле модульного тестирования?

...