I am using the .NET Chart Control library that comes with .NET 4.0 Beta 2 to create and save images to disk in the background stream. However, I do not display the diagram on the screen, just creating a diagram, saving it to disk and destroying it. Something like that:
public void GeneratePlot(IList<DataPoint> series, Stream outputStream) { using (var ch = new Chart()) { ch.ChartAreas.Add(new ChartArea()); var s = new Series(); foreach (var pnt in series) s.Points.Add(pnt); ch.Series.Add(s); ch.SaveImage(outputStream, ChartImageFormat.Png); } }
It took about 300-400 ms to create and save each chart. I have potentially hundreds of diagrams to create, so I decided to use Parallel.For() to parallelize these tasks. I have an 8-core machine, however, when I try to create 4 charts at a time, my chart creates / saves time, increasing anywhere from 800 to 1400 ms, almost all of which are consumed by Chart.SaveImage .
I thought this might be a disk I / O limitation, therefore, to check that I changed the last line to:
ch.SaveImage(Stream.Null, ChartImageFormat.Png);
Even when writing to zero stream, the performance is still approximately the same (800-1400 ms).
Should I not create images in the background thread in parallel with this library, or am I doing something wrong?
thanks
EDIT: Added full code example
Just change the flag passed to CreateCharts() to check concurrency and seriality.
using System; using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms.DataVisualization.Charting; namespace ConsoleChartTest { class Program { public static void GeneratePlot(IEnumerable<DataPoint> series, Stream outputStream) { long beginTime = Environment.TickCount; using (var ch = new Chart()) { ch.ChartAreas.Add(new ChartArea()); var s = new Series(); foreach (var pnt in series) s.Points.Add(pnt); ch.Series.Add(s); long endTime = Environment.TickCount; long createTime = endTime - beginTime; beginTime = Environment.TickCount; ch.SaveImage(outputStream, ChartImageFormat.Png); endTime = Environment.TickCount; long saveTime = endTime - beginTime; Console.WriteLine("Thread Id: {0,2} Create Time: {1,3} Save Time: {2,3}", Thread.CurrentThread.ManagedThreadId, createTime, saveTime); } } public static void CreateCharts(bool parallel) { var data = new DataPoint[20000]; for (int i = 0; i < data.Length; i++) { data[i] = new DataPoint(i, i); } if (parallel) { Parallel.For(0, 10, (i) => GeneratePlot(data, Stream.Null)); } else { for (int i = 0; i < 10; i++) GeneratePlot(data, Stream.Null); } } static void Main(string[] args) { Console.WriteLine("Main Thread Id: {0,2}", Thread.CurrentThread.ManagedThreadId); long beginTime = Environment.TickCount; CreateCharts(false); long endTime = Environment.TickCount; Console.WriteLine("Total Time: {0}", endTime - beginTime); } } }