Ich verwende die .NET Chart Control-Bibliothek, die mit .NET 4.0 Beta 2 kommt, um Bilder auf der Festplatte in einem Hintergrund-Thread zu erstellen und zu speichern. Ich zeige das Diagramm nicht auf dem Bildschirm, sondern erstelle einfach ein Diagramm, speichere es auf der Festplatte und zerstöre es. Etwas wie folgt aus:.NET Chart Control Parallel Performance
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);
}
}
Es wurde etwa 300 nehmen - 400 ms jedes Diagramm zu erstellen und zu speichern. Ich habe möglicherweise Hunderte von Diagrammen zu erstellen, also dachte ich, ich würde 10 verwenden, um diese Aufgaben zu parallelisieren. Ich habe einen 8-Kern-Rechner, aber wenn ich versuche, 4 Diagramme gleichzeitig zu erstellen, erhöht sich die Zeit zum Erstellen/Speichern meines Diagramms auf 800 bis 1400 ms, wobei fast alle von Chart.SaveImage
verbraucht werden.
Ich dachte, das eine Begrenzung der Platte sein könnte, I/O, so zu prüfen, dass ich die letzte Zeile geändert:
Schreibench.SaveImage(Stream.Null, ChartImageFormat.Png);
Auch auf eine Null die Leistung streamen noch etwa gleich ist (800 - 1400 ms).
Soll ich nicht parallel zu dieser Bibliothek Bilder auf Hintergrundthreads erstellen oder mache ich etwas falsch?
Dank
EDIT: hinzugefügt Vollständiges Codebeispiel
einfach die Fahne CreateCharts()
weitergegeben ändern im Vergleich zu seriellen parallel zu testen.
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);
}
}
}
Humor uns - können Sie den vollständigen Code veröffentlichen, einschließlich, wenn Sie 'Parallel.For' verwenden? Und geben Sie uns auch eine Vorstellung davon, wie Sie diesen Code instrumentieren, woher die Zahlen kommen? Wie sieht die CPU-Auslastung während Ihres Benchmarks aus? – Aaronaught
vielleicht ist das Problem in der Umwandlung, irgendwie können Sie mehr Code bekannt geben? –