使用自写图形控件时,我注意到在显示噪点数据时图的绘制要比显示干净数据时慢得多。
我进一步挖掘并将问题缩小到其最小差异:绘制具有相同Y值的具有不同Y值的绘制线的相同数量的线。绘制之字形线比绘制直线要慢
因此,举例来说,我将以下测试放在一起。我生成点列表,其中一个具有随机Y值,一个具有相同的Y值,另一个具有锯齿形Y型。
private List<PointF> GenerateRandom(int n, int width, int height)
{
//Generate random pattern
Random rnd = new Random();
float stepwidth = Convert.ToSingle(width/n);
float mid = Convert.ToSingle(height/2);
float lastx = 0;
float lasty = mid;
List<PointF> res = new List<PointF>();
res.Add(new PointF(lastx, lasty));
for (int i = 1; i <= n; i++)
{
var x = stepwidth * i;
var y = Convert.ToSingle(height * rnd.NextDouble());
res.Add(new PointF(x, y));
}
return res;
}
private List<PointF> GenerateUnity(int n, int width, int height)
{
//Generate points along a simple line
float stepwidth = Convert.ToSingle(width/n);
float mid = Convert.ToSingle(height/2);
float lastx = 0;
float lasty = mid;
List<PointF> res = new List<PointF>();
res.Add(new PointF(lastx, lasty));
for (int i = 1; i <= n; i++)
{
var x = stepwidth * i;
var y = mid;
res.Add(new PointF(x, y));
}
return res;
}
private List<PointF> GenerateZigZag(int n, int width, int height)
{
//Generate an Up/Down List
float stepwidth = Convert.ToSingle(width/n);
float mid = Convert.ToSingle(height/2);
float lastx = 0;
float lasty = mid;
List<PointF> res = new List<PointF>();
res.Add(new PointF(lastx, lasty));
var state = false;
for (int i = 1; i <= n; i++)
{
var x = stepwidth * i;
var y = mid - (state ? 50 : -50);
res.Add(new PointF(x, y));
state = !state;
}
return res;
}
我现在画点的每个列表几次,比较需要多长时间:
private void DoTheTest()
{
Bitmap bmp = new Bitmap(970, 512);
var random = GenerateRandom(2500, bmp.Width, bmp.Height).ToArray();
var unity = GenerateUnity(2500, bmp.Width, bmp.Height).ToArray();
var ZigZag = GenerateZigZag(2500, bmp.Width, bmp.Height).ToArray();
using (Graphics g = Graphics.FromImage(bmp))
{
var tUnity = BenchmarkDraw(g, 200, unity);
var tRandom = BenchmarkDraw(g, 200, random);
var tZigZag = BenchmarkDraw(g, 200, ZigZag);
MessageBox.Show(tUnity.ToString() + "\r\n" + tRandom.ToString() + "\r\n" + tZigZag.ToString());
}
}
private double BenchmarkDraw(Graphics g, int n, PointF[] Points)
{
var Times = new List<double>();
for (int i = 1; i <= n; i++)
{
g.Clear(Color.White);
System.DateTime d3 = DateTime.Now;
DrawLines(g, Points);
System.DateTime d4 = DateTime.Now;
Times.Add((d4 - d3).TotalMilliseconds);
}
return Times.Average();
}
private void DrawLines(Graphics g, PointF[] Points)
{
g.DrawLines(Pens.Black, Points);
}
我拿出每绘图以下持续时间:
Straight Line: 0.095 ms
Zig-Zag Pattern: 3.24 ms
Random Pattern: 5.47 ms
所以似乎逐渐变得越来越糟糕,绘制线条的变化越大,这也是我在开始时提到的控制绘画中遇到的真实世界效果。
我的问题是这样如下:
- 为什么会做出如此残酷的差异,这行是要绘制?
- 如何提高噪音数据的绘图速度?
忽略一个事实,即bechmarks总是很难得到正确的答案,而不是错误的:1)根据y变化,你的线可能会变长__lot__。你应该从结果中消除这种差异。 2)如果直线不是更快,我会感到惊讶,因为这意味着gdi例程不会识别它们,并错过了优化的好机会。即使是快速线路算法也必须比直接水平/垂直直线运动要慢,因为根本不需要算法,也不需要保持斜率不能去除步骤的滑动。 – TaW
3)您可能需要测试各种平滑模式。即使有轻微的倾斜也会导致大约2-3倍的像素数量,必须在中心线上方和下方涂漆。 – TaW
@TaW妈的,我认为你的第一点是正确的,现在你指出了这点。如果用平均线长划分,随机和曲折时间会收敛。直线实际上是最慢的,但这可能意味着某种其他开销。所以这就是其中的原因,如果有的话要考虑一下。但是优化线条绘制是另一个问题。你会添加一个答案吗? – Jens