動的データ表示を使用していくつかのプロットを描画しています。
マーカーを画面にレンダリングするための MarkerPointsGraph というクラスを提供します。OnRender メソッドは Render 中に呼び出され、これが適切なマーカー (Circle、Triangle など) の render メソッドを呼び出します。
protected override void OnRenderCore(DrawingContext dc, RenderState state)
{
if (DataSource == null) return;
if (Marker == null) return;
var transform = Plotter2D.Viewport.Transform;
DataRect bounds = DataRect.Empty;
using (IPointEnumerator enumerator = DataSource.GetEnumerator(GetContext()))
{
Point point = new Point();
while (enumerator.MoveNext())
{
enumerator.GetCurrent(ref point);
enumerator.ApplyMappings(Marker);
//Point screenPoint = point.Transform(state.Visible, state.Output);
Point screenPoint = point.DataToScreen(transform);
bounds = DataRect.Union(bounds, point);
Marker.Render(dc, screenPoint);
}
}
Viewport2D.SetContentBounds(this, bounds);
}
/// <summary>Renders circle around each point of graph</summary>
public class CirclePointMarker : ShapePointMarker {
public override void Render(DrawingContext dc, Point screenPoint) {
dc.DrawEllipse(Fill, Pen, screenPoint, Size / 2, Size / 2);
}
}
今、私の呼び出しコードは以下の通りです。
plotter.AddLineGraph(
data.Data,
new Pen
{
Brush = Brushes.Violet,
DashStyle = DashStyles.DashDot,
Thickness = 3
},
GetMarker(data),
new StandardDescription(data.Title));
パフォーマンスで気付いた主な違いは、以下のメソッドにあります。
ChartData クラスからのデータの参照
private ShapePointMarker GetMarker(ChartData data)
{
ShapePointMarker marker = null;
switch (data.MarkerShape)
{
case Shapes.Circle:
marker = new CirclePointMarker();
break;
case Shapes.Triangle:
marker = new TrianglePointMarker();
break;
case Shapes.None:
default:
marker = null;
break;
}
if (marker != null)
{
//Referring to stuff here.
marker.Fill = new SolidColorBrush(data.MarkerColor);
marker.Size = data.MarkerSize;
}
return marker;
}
参照の代わりにデータをハードコーディングします。
private ShapePointMarker GetMarker(ChartData data)
{
ShapePointMarker marker = null;
switch (data.MarkerShape)
{
case Shapes.Circle:
marker = new CirclePointMarker();
break;
case Shapes.Triangle:
marker = new TrianglePointMarker();
break;
case Shapes.None:
default:
marker = null;
break;
}
if (marker != null)
{
//Hard coding stuff here.
marker.Fill = Brushes.Red;
marker.Size = 5;
}
return marker;
}
GetMarker メソッドの参照ベースのデータをハードコードされた値に変更するだけで、レンダリング時間が 100 倍近く改善されました。
この違いの原因となる C# の動作は何ですか?
編集: MarkerPointsGraph は、各ポイントのマーカーのオブジェクトを作成しません。render メソッドを呼び出すだけです。