123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Copyright (c) .NET Foundation. All rights reserved.
- // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
- using System;
- using System.IO;
- using System.Reflection;
- using System.Runtime;
- using System.Threading;
- using Benchmarks.Configuration;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- namespace Benchmarks
- {
- public class Program
- {
- public static string[] Args;
- public static string Server;
- public static void Main(string[] args)
- {
- Args = args;
- Console.WriteLine();
- Console.WriteLine("ASP.NET Core Benchmarks");
- Console.WriteLine("-----------------------");
- Console.WriteLine($"Current directory: {Directory.GetCurrentDirectory()}");
- Console.WriteLine($"WebHostBuilder loading from: {typeof(WebHostBuilder).GetTypeInfo().Assembly.Location}");
- var config = new ConfigurationBuilder()
- .AddCommandLine(args)
- .AddEnvironmentVariables(prefix: "ASPNETCORE_")
- .AddJsonFile("hosting.json", optional: true)
- .Build();
- Server = config["server"] ?? "Kestrel";
- var webHostBuilder = new WebHostBuilder()
- .UseContentRoot(Directory.GetCurrentDirectory())
- .UseConfiguration(config)
- .UseStartup<Startup>()
- .ConfigureServices(services => services
- .AddSingleton(new ConsoleArgs(args))
- .AddSingleton<IScenariosConfiguration, ConsoleHostScenariosConfiguration>()
- .AddSingleton<Scenarios>()
- )
- .UseDefaultServiceProvider(
- (context, options) => options.ValidateScopes = context.HostingEnvironment.IsDevelopment());
- if (String.Equals(Server, "Kestrel", StringComparison.OrdinalIgnoreCase))
- {
- var threads = GetThreadCount(config);
- webHostBuilder = webHostBuilder.UseKestrel();
- if (threads > 0)
- {
- webHostBuilder = webHostBuilder.UseLibuv(options => options.ThreadCount = threads);
- }
- }
- else if (String.Equals(Server, "HttpSys", StringComparison.OrdinalIgnoreCase))
- {
- webHostBuilder = webHostBuilder.UseHttpSys();
- }
- else
- {
- throw new InvalidOperationException($"Unknown server value: {Server}");
- }
- var webHost = webHostBuilder.Build();
- Console.WriteLine($"Using server {Server}");
- Console.WriteLine($"Server GC is currently {(GCSettings.IsServerGC ? "ENABLED" : "DISABLED")}");
- var nonInteractiveValue = config["NonInteractive"];
- if (nonInteractiveValue == null || !bool.Parse(nonInteractiveValue))
- {
- StartInteractiveConsoleThread();
- }
- webHost.Run();
- }
- private static void StartInteractiveConsoleThread()
- {
- // Run the interaction on a separate thread as we don't have Console.KeyAvailable on .NET Core so can't
- // do a pre-emptive check before we call Console.ReadKey (which blocks, hard)
- var started = new ManualResetEvent(false);
- var interactiveThread = new Thread(() =>
- {
- Console.WriteLine("Press 'C' to force GC or any other key to display GC stats");
- Console.WriteLine();
- started.Set();
- while (true)
- {
- var key = Console.ReadKey(intercept: true);
- if (key.Key == ConsoleKey.C)
- {
- Console.WriteLine();
- Console.Write("Forcing GC...");
- GC.Collect();
- GC.WaitForPendingFinalizers();
- GC.Collect();
- Console.WriteLine(" done!");
- }
- else
- {
- Console.WriteLine();
- Console.WriteLine($"Allocated: {GetAllocatedMemory()}");
- Console.WriteLine($"Gen 0: {GC.CollectionCount(0)}, Gen 1: {GC.CollectionCount(1)}, Gen 2: {GC.CollectionCount(2)}");
- }
- }
- })
- {
- IsBackground = true
- };
- interactiveThread.Start();
- started.WaitOne();
- }
- private static string GetAllocatedMemory(bool forceFullCollection = false)
- {
- double bytes = GC.GetTotalMemory(forceFullCollection);
- return $"{((bytes / 1024d) / 1024d).ToString("N2")} MB";
- }
- private static int GetThreadCount(IConfigurationRoot config)
- {
- var threadCountValue = config["threadCount"];
- return threadCountValue == null ? -1 : int.Parse(threadCountValue);
- }
- }
- }
|