public AbReport(ExecuteResult[] results, ExecuteScenario executeScenario, string scalingType) { ScalingType = scalingType; ScenarioName = executeScenario.ScenarioName; RequestCount = executeScenario.ProcessCount * executeScenario.WorkerPerProcess * executeScenario.ExecutePerWorker; Concurrency = executeScenario.WorkerPerProcess; TotalRequests = results.Length; CompleteRequests = results.Where(x => !x.HasError).Count(); FailedRequests = results.Where(x => x.HasError).Count(); // Time to complete all requests. // * Get sum of IWorkerReciever.Execute time on each workerId, max execution time will be actual execution time. TimeTaken = results.GroupBy(x => x.WorkerId).Select(xs => xs.Sum(x => x.Elapsed.TotalSeconds)).Max(); // The average time spent per request. The first value is calculated with the formula `concurrency * timetaken * 1000 / done` while the second value is calculated with the formula `timetaken * 1000 / done` TimePerRequest = TimeTaken * 1000 / RequestCount; // percentile requires sort before calculate var sortedResultsElapsedMs = results.Select(x => x.Elapsed.TotalMilliseconds).OrderBy(x => x).ToArray(); var percecs = new[] { 0.5, 0.66, 0.75, 0.80, 0.90, 0.95, 0.98, 0.99, 1.00 }; Percentiles = percecs.Select((x, i) => { var percent = (int)(x * 100); var value = (int)MatchUtils.Percentile(sortedResultsElapsedMs, x); return(i != percecs.Length - 1 ? new PercentileData(percent, value, null) : new PercentileData(percent, value, "(longest request)")); }) .ToArray(); }