private void TestInvoke <T>(Expression <Func <BenchmarkAllCases, T> > methodCall, int unrollFactor, object expectedResult) { var targetMethod = ((MethodCallExpression)methodCall.Body).Method; var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod); // Run mode var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, false, expectedResult); action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, false, expectedResult); // Idle mode bool isValueTask = typeof(T).IsConstructedGenericType && typeof(T).GetGenericTypeDefinition() == typeof(ValueTask <>); object idleExpected; if (isValueTask) { idleExpected = GetDefault(typeof(T).GetGenericArguments()[0]); } else if (typeof(T).GetTypeInfo().IsValueType) { idleExpected = 0; } else if (expectedResult == null || typeof(T) == typeof(Task)) { idleExpected = null; } else { idleExpected = GetDefault(expectedResult.GetType()); } action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, true, idleExpected); action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, true, idleExpected); }
private void TestInvoke(Expression <Action <BenchmarkAllCases> > methodCall, int unrollFactor) { var targetMethod = ((MethodCallExpression)methodCall.Body).Method; var target = new Target(typeof(BenchmarkAllCases), targetMethod, targetMethod, targetMethod); // Run mode var action = BenchmarkActionFactory.CreateRun(target, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, false, null); action = BenchmarkActionFactory.CreateRun(target, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, false, null); // Idle mode action = BenchmarkActionFactory.CreateIdle(target, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateIdle(target, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, true, null); // Setup/cleanup action = BenchmarkActionFactory.CreateSetup(target, new BenchmarkAllCases()); TestInvoke(action, 1, false, null); action = BenchmarkActionFactory.CreateCleanup(target, new BenchmarkAllCases()); TestInvoke(action, 1, false, null); // Setup/cleanup (empty) target = new Target(typeof(BenchmarkAllCases), targetMethod); action = BenchmarkActionFactory.CreateSetup(target, new BenchmarkAllCases()); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateCleanup(target, new BenchmarkAllCases()); TestInvoke(action, unrollFactor, true, null); // Dummy (just in case something may broke) action = BenchmarkActionFactory.CreateDummy(); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateDummy(); TestInvoke(action, unrollFactor, true, null); }
private void TestInvoke(Expression <Action <BenchmarkAllCases> > methodCall, int unrollFactor) { var targetMethod = ((MethodCallExpression)methodCall.Body).Method; var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod, targetMethod, targetMethod); // Run mode var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, false, null); action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, false, null); // Idle mode action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor); TestInvoke(action, unrollFactor, true, null); // GlobalSetup/GlobalCleanup action = BenchmarkActionFactory.CreateGlobalSetup(descriptor, new BenchmarkAllCases()); TestInvoke(action, 1, false, null); action = BenchmarkActionFactory.CreateGlobalCleanup(descriptor, new BenchmarkAllCases()); TestInvoke(action, 1, false, null); // GlobalSetup/GlobalCleanup (empty) descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod); action = BenchmarkActionFactory.CreateGlobalSetup(descriptor, new BenchmarkAllCases()); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateGlobalCleanup(descriptor, new BenchmarkAllCases()); TestInvoke(action, unrollFactor, true, null); // Dummy (just in case something may broke) action = BenchmarkActionFactory.CreateDummy(); TestInvoke(action, unrollFactor, true, null); action = BenchmarkActionFactory.CreateDummy(); TestInvoke(action, unrollFactor, true, null); }
static void Main(string[] args) { // Pick a benchmark. var availableBenchmarks = Benchmarks.Benchmarks.All; if (args.Length == 0) { Console.WriteLine("Must provide the name of a benchmark class. (e.g. ./Autofac.BenchmarkProfiling.exe ChildScopeResolveBenchmark)"); Console.WriteLine("Possible benchmarks are:"); PrintBenchmarks(availableBenchmarks); return; } var inputType = args[0]; var selectedBenchmark = availableBenchmarks.FirstOrDefault(x => x.Name.Equals(inputType, StringComparison.InvariantCultureIgnoreCase)); if (selectedBenchmark is null) { Console.WriteLine("Specified benchmark does not exist."); PrintBenchmarks(availableBenchmarks); return; } var benchRunInfo = BenchmarkConverter.TypeToBenchmarks(selectedBenchmark); BenchmarkCase selectedCase = null; if (benchRunInfo.BenchmarksCases.Length == 0) { Console.WriteLine("No benchmark cases in specified benchmark."); return; } else if (benchRunInfo.BenchmarksCases.Length == 1) { selectedCase = benchRunInfo.BenchmarksCases[0]; } else { // Multiple benchmark cases. Has one been supplied? if (args.Length > 1) { if (uint.TryParse(args[1], out var selection)) { if (selection < benchRunInfo.BenchmarksCases.Length) { selectedCase = benchRunInfo.BenchmarksCases[selection]; } else { Console.WriteLine("Invalid benchmark case number provided. Possible options are: "); PrintCases(benchRunInfo); } } else { Console.WriteLine("Cannot parse provided benchmark case selection."); return; } } else { Console.WriteLine("Specified benchmark has multiple possible cases; a single case must be specified. Possible options are:"); PrintCases(benchRunInfo); return; } } var benchInstance = Activator.CreateInstance(selectedCase.Descriptor.Type); var setupAction = BenchmarkActionFactory.CreateGlobalSetup(selectedCase.Descriptor, benchInstance); var cleanupAction = BenchmarkActionFactory.CreateGlobalCleanup(selectedCase.Descriptor, benchInstance); // Workload method is generated differently when BenchmarkDotNet actually runs; we'll need to wrap it in the set of parameters. // It's way slower than they way they do it, but it should still give us good profiler results. Action <int> workloadAction = (repeat) => { while (repeat > 0) { selectedCase.Descriptor.WorkloadMethod.Invoke(benchInstance, selectedCase.Parameters.Items.Select(x => x.Value).ToArray()); repeat--; } }; setupAction.InvokeSingle(); // Warmup. workloadAction(100); // Now start a new thread. var runThread = new Thread(new ThreadStart(() => { // Do a lot. workloadAction(10000); })) { Name = "Workload Thread" }; runThread.Start(); runThread.Join(); cleanupAction.InvokeSingle(); }