/// <summary> /// Initializes a new instance of the <see cref="PerfSummary"/> class. /// </summary> public PerfSummary(List <PerfEntity> data) { PerfEntity e = data[0]; this.MachineName = e.MachineName; this.RuntimeVersion = e.RuntimeVersion; this.CommitId = e.CommitId; this.Data = data; this.TestName = e.TestName; this.Date = DateTime.Now.ToUniversalTime(); this.PartitionKey = string.Format("{0}.{1}", e.MachineName, e.RuntimeVersion); this.Id = string.Format("{0}.{1}", e.CommitId, e.TestName); // summaryize the data. double meanTime = MathHelpers.Mean(from i in data select i.Time); double meanMemory = MathHelpers.Mean(from i in data select i.Memory); double meanCpu = MathHelpers.Mean(from i in data select i.Cpu); double meanStdDevTime = MathHelpers.Mean(from i in data select i.TimeStdDev); double meanStdDevMemory = MathHelpers.Mean(from i in data select i.MemoryStdDev); double meanStdDevCpu = MathHelpers.Mean(from i in data select i.CpuStdDev); if (meanStdDevTime is 0) { meanStdDevTime = MathHelpers.StandardDeviation(from i in data select i.Time); meanStdDevMemory = MathHelpers.StandardDeviation(from i in data select i.Memory); meanStdDevCpu = MathHelpers.StandardDeviation(from i in data select i.Cpu); } double timeSlope = MathHelpers.LinearRegression(MathHelpers.ToDataPoints(from i in data select i.Time)).Slope / meanTime; double memSlope = MathHelpers.LinearRegression(MathHelpers.ToDataPoints(from i in data select i.Memory)).Slope / meanMemory; double cpuSlope = MathHelpers.LinearRegression(MathHelpers.ToDataPoints(from i in data select i.Cpu)).Slope / meanCpu; // more than 10% slope we have a problem! if (timeSlope > 0.1) { this.Comments = "Slow down?"; } else if (memSlope > 0.1) { this.Comments = "Memory leak?"; } else if (cpuSlope > 0.1) { this.Comments = "Thread leak?"; } this.TimeMean = meanTime; this.TimeStdDev = meanStdDevTime; this.TimeSlope = timeSlope; this.MemoryMean = meanMemory; this.MemoryStdDev = meanStdDevMemory; this.MemorySlope = memSlope; this.CpuMean = meanCpu; this.CpuStdDev = meanStdDevCpu; this.CpuSlope = cpuSlope; }
private void SaveReport(List <PerfEntity> data) { var testName = data[0].TestName.Split(' ')[0]; string filename = Path.Combine(this.OutputDir, testName + ".csv"); bool writeHeaders = !File.Exists(filename); using (StreamWriter writer = new StreamWriter(filename, true, Encoding.UTF8)) { if (writeHeaders) { PerfEntity.WriteHeaders(writer); } foreach (var item in data) { item.WriteCsv(writer); } } }
private List <PerfEntity> GetEntities(BenchmarkReport report) { List <PerfEntity> results = new List <PerfEntity>(); string testName = report.BenchmarkCase.Descriptor.DisplayInfo; foreach (var p in report.BenchmarkCase.Parameters.Items) { testName += string.Format(" {0}={1}", p.Name, p.Value); } // Right now we are choosing NOT to return each test result as // a separate entity, as this is too much information, so for now // we return the "Min" time from this run, based on the idea that the // minimum time has the least OS noise in it so it should be more stable. List <double> times = new List <double>(); foreach (var row in report.GetResultRuns()) { double msPerTest = row.Nanoseconds / 1000000.0 / row.Operations; times.Add(msPerTest); } var entity = new PerfEntity(this.MachineName, this.RuntimeVersion, this.CommitId, testName, 0) { Time = times.Min(), TimeStdDev = MathHelpers.StandardDeviation(times), }; if (report.Metrics.ContainsKey("CPU")) { entity.Cpu = report.Metrics["CPU"].Value; } if (report.Metrics.ContainsKey("TotalMemory")) { entity.Memory = report.Metrics["TotalMemory"].Value; } results.Add(entity); return(results); }