// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2014 OxyPlot contributors // // // A performance test program. // // -------------------------------------------------------------------------------------------------------------------- namespace PerformanceTest { using System; using System.Collections.Generic; using System.Diagnostics; using OxyPlot; using OxyPlot.Series; /// /// A performance test program. /// /// /// Build with the Release configuration. /// To be used with a profiler or as a standalone program (remember to run outside the Visual Studio IDE). /// public class Program { /// /// The program entry point. /// public static void Main() { var testModels = new Dictionary { { "LineSeries with 100000 points", CreateModel(100000) }, { "LineSeries with 100000 points in ItemsSource", CreateModel2(100000) } }; foreach (var kvp in testModels) { Console.WriteLine(kvp.Key); TestModelUpdate(kvp.Value); TestModelRender(kvp.Value); Console.WriteLine(); } Console.WriteLine("DrawClippedLine test:"); var t0 = TestDrawClippedLine(10000, 1000, false); var t1 = TestDrawClippedLine(10000, 1000, true); Console.WriteLine("{0:P1}", (t0 - t1) / t0); Console.ReadKey(); } public static double TestModelUpdate(PlotModel model, int m = 1000) { var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { ((IPlotModel)model).Update(true); } stopwatch.Stop(); Console.WriteLine("Update: {0}", (double)stopwatch.ElapsedMilliseconds); return stopwatch.ElapsedMilliseconds; } public static double TestModelRender(PlotModel model, int m = 100) { var rc = new EmptyRenderContext(); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { ((IPlotModel)model).Render(rc, 800, 600); } stopwatch.Stop(); Console.WriteLine("Render: {0}", (double)stopwatch.ElapsedMilliseconds); return stopwatch.ElapsedMilliseconds; } private static PlotModel CreateModel(int n) { var model = new PlotModel(); var series = new LineSeries(); for (int i = 0; i < n; i++) { series.Points.Add(new DataPoint(i, Math.Sin(i))); } model.Series.Add(series); ((IPlotModel)model).Update(true); return model; } private static PlotModel CreateModel2(int n) { var points = new List(); for (int i = 0; i < n; i++) { points.Add(new DataPoint(i, Math.Sin(i))); } var model = new PlotModel(); var series = new LineSeries(); series.ItemsSource = points; model.Series.Add(series); ((IPlotModel)model).Update(true); return model; } /// /// Tests the method. /// /// The number of points. /// The number of repetitions. /// true to use an output buffer. /// The elapsed time in milliseconds. public static double TestDrawClippedLine(int n, int m, bool useOutputBuffer) { var points = new ScreenPoint[n]; for (int i = 0; i < n; i++) { points[i] = new ScreenPoint((double)i / n, Math.Sin(40d * i / n)); } var clippingRectangle = new OxyRect(0.3, -0.5, 0.5, 1); var rc = new EmptyRenderContext(); var outputBuffer = useOutputBuffer ? new List(n) : null; var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { rc.DrawClippedLine( clippingRectangle, points, 1, OxyColors.Black, 1, null, LineJoin.Miter, false, outputBuffer); } stopwatch.Stop(); Console.WriteLine((double)stopwatch.ElapsedMilliseconds); return stopwatch.ElapsedMilliseconds; } } }