使用自寫圖形控件時,我注意到在顯示噪點數據時圖的繪製要比顯示乾淨數據時慢得多。
我進一步挖掘並將問題縮小到其最小差異:繪製具有相同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