При использовании самописного управления графикой я заметил, что картина графика была намного медленнее при отображении шумных данных, чем при отображении чистых данных.
Я вникнул и сузил проблему до ее минимальной минимальной разницы: рисовал то же количество линий с переменными значениями Y по сравнению с линиями рисования с тем же значением Y.Рисование линий зигзага намного медленнее, чем рисование прямых линий.
Так, например, я собрал следующие тесты. Я генерирую списки точек, один со случайными значениями Y, один с тем же Y, и один с шаблоном Zig-Zag 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) вы можете протестировать различные сглаживающие моды. с antaliasing даже небольшой уклон приведет к примерно в 2-3 раза больше пикселей, которые должны быть окрашены выше и ниже центральной линии. – TaW
@TaW Черт, я думаю, что ваш первый пункт правильный и даже совершенно очевидный, когда вы указываете его. Если я разделяю среднюю длину строки, случайные и зигзагообразные времена сходятся. Прямая на самом деле самая медленная, но это может означать лишь некоторые другие накладные расходы. Так вот в чем причина, подумать об этом, если есть. Но оптимизировать рисование линии - еще один вопрос. Не могли бы вы добавить ответ? – Jens