我正在使用动态数据显示来绘制一些图。
它提供了一个名为 MarkerPointsGraph 的类来将标记呈现到屏幕上。OnRender 方法在 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 不会为每个点创建一个 Marker 对象。它只是调用 render 方法。