У меня есть несколько задач, которые выполняются значительно медленнее при запуске в консольном приложении по сравнению с 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 по сравнению с работой в качестве консольного приложения или в модуле модульного тестирования?