Я использую библиотеку .NET Chart Control, которая поставляется с .NET 4.0 Beta 2 для создания и сохранения изображений на диске в фоновом потоке. Однако я не показываю диаграмму на экране, просто создавая диаграмму, сохраняя ее на диск и уничтожая ее. Что-то вроде этого:.NET Chart Control Параллельная производительность
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);
}
}
Для создания и сохранения каждой диаграммы потребовалось около 300 - 400 мс. У меня есть потенциально сотни диаграмм для создания, поэтому я решил использовать Parallel.For()
для параллелизации этих задач. У меня есть 8-ядерная машина, однако, когда я пытаюсь создать 4 диаграммы за раз, моя диаграмма создает/экономит время, увеличивается в любом месте от 800 до 1400 мс, почти все из которых потребляются Chart.SaveImage
.
Я думал, что это может быть ограничение дискового ввода/вывода, поэтому, чтобы проверить, что я изменил последнюю строку на:
ch.SaveImage(Stream.Null, ChartImageFormat.Png);
Даже запись в нулевой поток производительность еще примерно такой же (800 - 1400 мс).
Я не должен создавать изображения на фоне потоков параллельно с этой библиотекой, или я делаю что-то неправильно?
Благодаря
EDIT: Добавлен полный Пример кода
Просто изменить флаг передается CreateCharts()
испытать параллельно по сравнению с серийным.
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);
}
}
}
Юмор нас - вы можете разместить полный код, в том числе, где вы используете 'Parallel.For'? А также дать нам некоторое представление о том, как вы применяете этот код, откуда поступают цифры? Как выглядит использование ЦП во время бенчмаркинга? – Aaronaught
может быть проблема в преобразовании, в любом случае вы можете разместить больше кода? –