Exemple #1
0
        List <ResultTableRowModel> BuildRowModels(Func <Benchmark, Metric, bool> primaryMetricSelector)
        {
            List <ResultTableRowModel> rows = new List <ResultTableRowModel>();

            foreach (Benchmark benchmark in Benchmarks)
            {
                BenchmarkRunResult canonResult = BenchmarkRunResults.Where(r => r.Benchmark == benchmark).FirstOrDefault();
                if (canonResult == null || canonResult.IterationResults == null || canonResult.IterationResults.Count == 0)
                {
                    continue;
                }
                IterationResult canonIteration = canonResult.IterationResults[0];
                foreach (Metric metric in canonIteration.Measurements.Keys)
                {
                    if (primaryMetricSelector(benchmark, metric))
                    {
                        rows.Add(new ResultTableRowModel()
                        {
                            Benchmark = benchmark, Metric = metric
                        });
                    }
                }
            }
            return(rows);
        }
Exemple #2
0
        protected override IterationResult RecordIterationMetrics(ScenarioExecutionResult scenarioIteration, string stdout, string stderr, ITestOutputHelper output)
        {
            IterationResult result = base.RecordIterationMetrics(scenarioIteration, stdout, stderr, output);

            AddConsoleMetrics(result, stdout, output);
            return(result);
        }
Exemple #3
0
        protected virtual IterationResult RecordIterationMetrics(ScenarioExecutionResult scenarioIteration, string stdout, string stderr, ITestOutputHelper output)
        {
            IterationResult iterationResult = new IterationResult();
            int             elapsedMs       = (int)(scenarioIteration.ProcessExitInfo.ExitTime - scenarioIteration.ProcessExitInfo.StartTime).TotalMilliseconds;

            iterationResult.Measurements.Add(Metric.ElapsedTimeMilliseconds, elapsedMs);
            if (!string.IsNullOrWhiteSpace(scenarioIteration.EventLogFileName) && File.Exists(scenarioIteration.EventLogFileName))
            {
                AddEtwData(iterationResult, scenarioIteration, output);
            }
            return(iterationResult);
        }
        /// <summary>
        /// Converts IterationResult into Benchview's IterationModel, remaping and filtering the metrics reported
        /// </summary>
        static IterationModel ConvertIterationResult(IterationResult iterationResult, Func <Metric, Metric> metricMapping)
        {
            IterationModel iterationModel = new IterationModel();

            iterationModel.Iteration = new Dictionary <string, double>();
            foreach (KeyValuePair <Metric, double> measurement in iterationResult.Measurements)
            {
                Metric finalMetric = metricMapping(measurement.Key);
                if (!finalMetric.Equals(default(Metric)))
                {
                    iterationModel.Iteration.Add(finalMetric.Name, measurement.Value);
                }
            }
            return(iterationModel);
        }
Exemple #5
0
        void AddConsoleMetrics(IterationResult result, string stdout, ITestOutputHelper output)
        {
            output.WriteLine("Processing iteration results.");

            double?trainingTime            = null;
            double?firstSearchTime         = null;
            double?steadyStateMedianTime   = null;
            var    currentDecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

            using (var reader = new StringReader(stdout))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    Match match = Regex.Match(line, @"^Training took \s*(\d+)ms$");
                    if (match.Success && match.Groups.Count == 2)
                    {
                        trainingTime = Convert.ToDouble(match.Groups[1].Value);
                        continue;
                    }

                    match = Regex.Match(line, @"^Search took \s*(\d+)ms$");
                    if (match.Success && match.Groups.Count == 2)
                    {
                        firstSearchTime = Convert.ToDouble(match.Groups[1].Value);
                        continue;
                    }

                    match = Regex.Match(line, $@"^Steadystate median search time: \s*(\d+\{currentDecimalSeparator}\d+)ms$");
                    if (match.Success && match.Groups.Count == 2)
                    {
                        //many lines will match, but the final values of these variables will be from the last batch which is presumably the
                        //best measurement of steady state performance
                        steadyStateMedianTime = Convert.ToDouble(match.Groups[1].Value);
                        continue;
                    }
                }
            }

            if (!trainingTime.HasValue)
            {
                throw new FormatException("Training time was not found.");
            }
            if (!firstSearchTime.HasValue)
            {
                throw new FormatException("First Search time was not found.");
            }
            if (!steadyStateMedianTime.HasValue)
            {
                throw new FormatException("Steady state median response time not found.");
            }


            result.Measurements.Add(TrainingMetric, trainingTime.Value);
            result.Measurements.Add(FirstSearchMetric, firstSearchTime.Value);
            result.Measurements.Add(MedianSearchMetric, steadyStateMedianTime.Value);

            output.WriteLine($"Training took {trainingTime}ms");
            output.WriteLine($"Search took {firstSearchTime}ms");
            output.WriteLine($"Median steady state search {steadyStateMedianTime.Value}ms");
        }
Exemple #6
0
        protected static void AddEtwData(
            IterationResult iteration,
            ScenarioExecutionResult scenarioExecutionResult,
            ITestOutputHelper output)
        {
            string[] modulesOfInterest = new string[] {
                "Anonymously Hosted DynamicMethods Assembly",
                "clrjit.dll",
                "coreclr.dll",
                "dotnet.exe",
                "MusicStore.dll",
                "AllReady.dll",
                "Word2VecScenario.dll",
                "ntoskrnl.exe",
                "System.Private.CoreLib.dll",
                "Unknown",
            };

            // Get the list of processes of interest.
            try
            {
                var processes = new SimpleTraceEventParser().GetProfileData(scenarioExecutionResult);

                // Extract the Pmc data for each one of the processes.
                foreach (var process in processes)
                {
                    if (process.Id != scenarioExecutionResult.ProcessExitInfo.ProcessId)
                    {
                        continue;
                    }

                    iteration.Measurements.Add(new Metric($"PMC/{process.Name}/Duration", "ms"),
                                               process.LifeSpan.Duration.TotalMilliseconds);

                    // Add process metrics values.
                    foreach (var pmcData in process.PerformanceMonitorCounterData)
                    {
                        iteration.Measurements.Add(new Metric($"PMC/{process.Name}/{pmcData.Key.Name}", pmcData.Key.Unit), pmcData.Value);
                    }

                    foreach (var module in process.Modules)
                    {
                        var moduleName = Path.GetFileName(module.FullName);
                        if (modulesOfInterest.Any(m => m.Equals(moduleName, StringComparison.OrdinalIgnoreCase)))
                        {
                            foreach (var pmcData in module.PerformanceMonitorCounterData)
                            {
                                Metric m = new Metric($"PMC/{process.Name}!{moduleName}/{pmcData.Key.Name}", pmcData.Key.Unit);
                                // Sometimes the etw parser gives duplicate module entries which leads to duplicate keys
                                // but I haven't hunted down the reason. For now it is first one wins.
                                if (!iteration.Measurements.ContainsKey(m))
                                {
                                    iteration.Measurements.Add(m, pmcData.Value);
                                }
                            }
                        }
                    }
                }
            }
            catch (InvalidOperationException e)
            {
                output.WriteLine("Error while processing ETW log: " + scenarioExecutionResult.EventLogFileName);
                output.WriteLine(e.ToString());
            }
        }