Program.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using System.IO;
  5. using System.Runtime;
  6. using System.Threading;
  7. using Benchmarks.Configuration;
  8. using Microsoft.AspNetCore.Hosting;
  9. using Microsoft.Extensions.Configuration;
  10. using Microsoft.Extensions.DependencyInjection;
  11. namespace Benchmarks
  12. {
  13. public class Program
  14. {
  15. public static string[] Args;
  16. public static string Server;
  17. public static void Main(string[] args)
  18. {
  19. Args = args;
  20. Console.WriteLine();
  21. Console.WriteLine("ASP.NET Core Benchmarks");
  22. Console.WriteLine("-----------------------");
  23. Console.WriteLine($"Current directory: {Directory.GetCurrentDirectory()}");
  24. var config = new ConfigurationBuilder()
  25. .AddCommandLine(args)
  26. .AddEnvironmentVariables(prefix: "ASPNETCORE_")
  27. .AddJsonFile("hosting.json", optional: true)
  28. .Build();
  29. Server = config["server"] ?? "Kestrel";
  30. var webHostBuilder = new WebHostBuilder()
  31. .UseContentRoot(Directory.GetCurrentDirectory())
  32. .UseConfiguration(config)
  33. .UseStartup<Startup>()
  34. .ConfigureServices(services => services
  35. .AddSingleton(new ConsoleArgs(args))
  36. .AddSingleton<IScenariosConfiguration, ConsoleHostScenariosConfiguration>()
  37. .AddSingleton<Scenarios>()
  38. );
  39. if (String.Equals(Server, "Kestrel", StringComparison.OrdinalIgnoreCase))
  40. {
  41. var threads = GetThreadCount(config);
  42. webHostBuilder = webHostBuilder.UseKestrel((options) =>
  43. {
  44. if (threads > 0)
  45. {
  46. options.ThreadCount = threads;
  47. }
  48. });
  49. }
  50. else if (String.Equals(Server, "WebListener", StringComparison.OrdinalIgnoreCase))
  51. {
  52. webHostBuilder = webHostBuilder.UseWebListener();
  53. }
  54. else
  55. {
  56. throw new InvalidOperationException($"Unknown server value: {Server}");
  57. }
  58. var webHost = webHostBuilder.Build();
  59. Console.WriteLine($"Using server {Server}");
  60. Console.WriteLine($"Server GC is currently {(GCSettings.IsServerGC ? "ENABLED" : "DISABLED")}");
  61. var nonInteractiveValue = config["NonInteractive"];
  62. if (nonInteractiveValue == null || !bool.Parse(nonInteractiveValue))
  63. {
  64. StartInteractiveConsoleThread();
  65. }
  66. webHost.Run();
  67. }
  68. private static void StartInteractiveConsoleThread()
  69. {
  70. // Run the interaction on a separate thread as we don't have Console.KeyAvailable on .NET Core so can't
  71. // do a pre-emptive check before we call Console.ReadKey (which blocks, hard)
  72. var started = new ManualResetEvent(false);
  73. var interactiveThread = new Thread(() =>
  74. {
  75. Console.WriteLine("Press 'C' to force GC or any other key to display GC stats");
  76. Console.WriteLine();
  77. started.Set();
  78. while (true)
  79. {
  80. var key = Console.ReadKey(intercept: true);
  81. if (key.Key == ConsoleKey.C)
  82. {
  83. Console.WriteLine();
  84. Console.Write("Forcing GC...");
  85. GC.Collect();
  86. GC.WaitForPendingFinalizers();
  87. GC.Collect();
  88. Console.WriteLine(" done!");
  89. }
  90. else
  91. {
  92. Console.WriteLine();
  93. Console.WriteLine($"Allocated: {GetAllocatedMemory()}");
  94. Console.WriteLine($"Gen 0: {GC.CollectionCount(0)}, Gen 1: {GC.CollectionCount(1)}, Gen 2: {GC.CollectionCount(2)}");
  95. }
  96. }
  97. });
  98. interactiveThread.IsBackground = true;
  99. interactiveThread.Start();
  100. started.WaitOne();
  101. }
  102. private static string GetAllocatedMemory(bool forceFullCollection = false)
  103. {
  104. double bytes = GC.GetTotalMemory(forceFullCollection);
  105. return $"{((bytes / 1024d) / 1024d).ToString("N2")} MB";
  106. }
  107. private static int GetThreadCount(IConfigurationRoot config)
  108. {
  109. var threadCountValue = config["threadCount"];
  110. return threadCountValue == null ? -1 : int.Parse(threadCountValue);
  111. }
  112. }
  113. }