Форум: "Media";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];
ВнизАффинное преобразование GDI + Найти похожие ветки
← →
Рамиль © (2007-11-03 15:01) [0]Почему System.Drawing.Drawing2D.Matrix такой медленый?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private Matrix matrix;
private float[,] Aphin;
private int n = 100000;
public Form1()
{
InitializeComponent();
matrix = new Matrix();
matrix.Rotate(45);
matrix.Scale(1.2f, 3.4f);
Aphin = new float[3, 3];
float[] a = matrix.Elements;
Aphin[0, 0] = a[0];
Aphin[0, 1] = a[1];
Aphin[1, 0] = a[2];
Aphin[1, 1] = a[3];
Aphin[2, 0] = a[4];
Aphin[2, 1] = a[5];
Aphin[2, 2] = 1;
}
private void MyTransformPoints(PointF[] pts)
{
PointF p;
for (int i = 0; i < pts.Length; i++)
{
p = pts[i];
pts[i].X = p.X * Aphin[0, 0] + p.Y * Aphin[1, 0] + Aphin[2, 0];
pts[i].Y = p.X * Aphin[0, 1] + p.Y * Aphin[1, 1] + Aphin[2, 1];
}
}
private void button1_Click(object sender, EventArgs e)
{
PointF[] Points = new PointF[] {new PointF(12, 34), new PointF(56, 78)};
int Ticks = System.Environment.TickCount;
for (int i = 0; i < n; i++)
matrix.TransformPoints(Points);
Ticks = System.Environment.TickCount - Ticks;
MessageBox.Show(Ticks.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
PointF[] Points = new PointF[] { new PointF(12, 34), new PointF(56, 78) };
int Ticks = System.Environment.TickCount;
for (int i = 0; i < n; i++)
MyTransformPoints(Points);
Ticks = System.Environment.TickCount - Ticks;
MessageBox.Show(Ticks.ToString());
}
}
}
В первом случае результат ~ 4500
Во втором ~ 270
Или я чего то не понимаю?
← →
homm © (2007-11-03 20:11) [1]Забудь про производительность на дотенет. Тем более при использовании GDI+.
← →
Рамиль © (2007-11-03 20:53) [2]
> homm © (03.11.07 20:11) [1]
Причем здесь производительность .NET. Вот это ассемблер что ли:private void MyTransformPoints(PointF[] pts)
{
PointF p;
for (int i = 0; i < pts.Length; i++)
{
p = pts[i];
pts[i].X = p.X * Aphin[0, 0] + p.Y * Aphin[1, 0] + Aphin[2, 0];
pts[i].Y = p.X * Aphin[0, 1] + p.Y * Aphin[1, 1] + Aphin[2, 1];
}
}
Работает на порядок быстрее, чем стандартная функция. Мне интересно почему.
Я сравниваю код для .NET с кодом для .NET. Производительность .NET относительно нативного кода меня в данный момент АБСОЛЮТНО не интересут.
← →
Рамиль © (2007-11-06 09:09) [3]Ну скажите, как можно было реализовать умножение матрицы на вектор, что бы оно так тормозило?
← →
homm © (2007-11-06 09:38) [4]> [3] Рамиль © (06.11.07 09:09)
> Ну скажите, как можно было реализовать умножение матрицы
> на вектор, что бы оно так тормозило?
А ты не думаешь, что тормозит не тело функции, а ее вызов? Выкладывали здесь асемблерный код доступа к windows.forms.color.black или что-то в этом роде, там полный северный зверь. Здесь почти то-же самое, System.Drawing.Drawing2D.Matrix.TransformPoints, пока до нее дойдет в дереве сборок…
← →
Рамиль © (2007-11-06 13:09) [5]
> homm © (06.11.07 09:38) [4]
Мм..
Переделал пример(передаю сразу массив на 200 000 точек), matrix.TransformPoints стал выполняться в два раза медленнее чем MyTransofrmPoints в предыдущем примере (получается, что вызов matrix.TransformPoints всего лишь в два раза медленнее чем вызов Form1.MyTransformPoints). А MyTransformPoints вообще за 16.
Зависмость от количества точек линейная.using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private Matrix matrix;
private float[,] Aphin;
private PointF[] points;
public Form1()
{
InitializeComponent();
matrix = new Matrix();
matrix.Rotate(45);
matrix.Scale(1.2f, 3.4f);
Aphin = new float[3, 3];
float[] a = matrix.Elements;
Aphin[0, 0] = a[0];
Aphin[0, 1] = a[1];
Aphin[1, 0] = a[2];
Aphin[1, 1] = a[3];
Aphin[2, 0] = a[4];
Aphin[2, 1] = a[5];
Aphin[2, 2] = 1;
Random r = new Random();
points = new PointF[200000];
for (int i = 0; i < 200000; i++)
{
points[i].X = r.Next(1000);
points[i].Y = r.Next(1000);
}
}
public virtual void MyTransformPoints(PointF[] pts)
{
PointF p;
for (int i = 0; i < pts.Length; i++)
{
p = pts[i];
pts[i].X = p.X * Aphin[0, 0] + p.Y * Aphin[1, 0] + Aphin[2, 0];
pts[i].Y = p.X * Aphin[0, 1] + p.Y * Aphin[1, 1] + Aphin[2, 1];
}
}
private void button1_Click(object sender, EventArgs e)
{
int Ticks = System.Environment.TickCount;
matrix.TransformPoints(points);
Ticks = System.Environment.TickCount - Ticks;
Color c = Color.Black;
MessageBox.Show(Ticks.ToString());
}
private void button2_Click(object sender, EventArgs e)
{
int Ticks = System.Environment.TickCount;
MyTransformPoints(points);
Ticks = System.Environment.TickCount - Ticks;
MessageBox.Show(Ticks.ToString());
}
}
}
MyTransformPoints ~ 16
Matrix.TransformPoints ~ 550
← →
homm © (2007-11-06 13:19) [6]> Random r = new Random();
> points = new PointF[200000];
> for (int i = 0; i < 200000; i++)
> {
> points[i].X = r.Next(1000);
> points[i].Y = r.Next(1000);
Идея объектно-ориентированного программирования, доведенная до маразма.
← →
iZEN © (2007-11-06 19:13) [7]
> homm © (06.11.07 13:19) [6]
>
> > Random r = new Random();
> > points = new PointF[200000];
> > for (int i = 0; i < 200000; i++)
> > {
> > points[i].X = r.Next(1000);
> > points[i].Y = r.Next(1000);
>
> Идея объектно-ориентированного программирования, доведенная
> до маразма.
dotNet, в отличие от Java 6 Mustang, не умеет инлайнить Get/Set-методы. Каждое обращение к свойству ведёт к вызову геттера.
← →
homm © (2007-11-06 21:20) [8]> [7] iZEN © (06.11.07 19:13)
При чем здесь это? Я о том, что для 2-х функций Random и randomize, и одной переменной RandomSeed создан отдельный класс. В этом маразм. Что там вызывается, инлайн или прерывание биоса, мне без разницы.
← →
Рамиль © (2007-11-07 09:26) [9]Хочу проверить прямым вызовом из dll, но что-то я совсем запутался в этих типах.. Что надо передать в GdipTransformMatrixPoints и правильно ли она экспортирована:
[DllImport("gdiplus.dll", CharSet = CharSet.Auto)]
public static extern int GdipTransformMatrixPoints(IntPtr matrix, PointF[] pts, int count);
В CIL передается NativeMatrixIL_0017: ldfld native int System.Drawing.Drawing2D.Matrix::nativeMatrix
← →
Lamer@fools.ua © (2007-11-07 13:25) [10]>>iZEN © (06.11.07 19:13) [7]
Та фто Фы гафарите...public static class Program
{
public class Test
{
private int m_value;
public int Value
{
//[MethodImpl(MethodImplOptions.NoInlining)]
get
{
return m_value;
}
//[MethodImpl(MethodImplOptions.NoInlining)]
set
{
m_value = value;
}
}
}
public static void Main()
{
Test t = new Test();
00000000 push esi
00000001 mov ecx,963090h
00000006 call FFB21FAC
0000000b mov edx,eax
t.Value = 123;
0000000d mov dword ptr [edx+4],7Bh
int value = t.Value;
00000014 mov esi,dword ptr [edx+4]
Console.WriteLine(value);
00000017 cmp dword ptr ds:[02301084h],0
0000001e jne 0000002A
00000020 mov ecx,1
00000025 call 785158EC
0000002a mov ecx,dword ptr ds:[02301084h]
00000030 mov edx,esi
00000032 mov eax,dword ptr [ecx]
00000034 call dword ptr [eax+000000BCh]
0000003a pop esi
}
0000003b ret
public static class Program
{
public class Test
{
private int m_value;
public int Value
{
[MethodImpl(MethodImplOptions.NoInlining)]
get
{
return m_value;
}
[MethodImpl(MethodImplOptions.NoInlining)]
set
{
m_value = value;
}
}
}
public static void Main()
{
Test t = new Test();
00000000 push esi
00000001 mov ecx,963090h
00000006 call FFB21FAC
0000000b mov esi,eax
t.Value = 123;
0000000d mov ecx,esi
0000000f mov edx,7Bh
00000014 cmp dword ptr [ecx],ecx
00000016 call dword ptr ds:[009630CCh]
int value = t.Value;
0000001c mov ecx,esi
0000001e cmp dword ptr [ecx],ecx
00000020 call dword ptr ds:[009630C8h]
00000026 mov esi,eax
Console.WriteLine(value);
00000028 cmp dword ptr ds:[02301084h],0
0000002f jne 0000003B
00000031 mov ecx,1
00000036 call 785158EC
0000003b mov ecx,dword ptr ds:[02301084h]
00000041 mov edx,esi
00000043 mov eax,dword ptr [ecx]
00000045 call dword ptr [eax+000000BCh]
0000004b pop esi
}
0000004c ret
← →
iZEN © (2007-11-08 16:29) [11]00000016 call dword ptr ds:[009630CCh]
и
00000020 call dword ptr ds:[009630C8h]
00000026 mov esi,eax
Ну точно не инлайнит.
← →
Lamer@fools.ua © (2007-11-12 12:52) [12]>Ну точно не инлайнит.
И не удивительно. Особенно для тех, кто умеет внимательно читать.
← →
Рамиль © (2007-11-12 13:05) [13]Вы бы лучше по теме что нибудь сказали... Я даже готов согласится, что круче Java ничего нет (но на ней переделывать не буду) :-D
← →
homm © (2007-11-12 13:38) [14]> [13] Рамиль © (12.11.07 13:05)
> Вы бы лучше по теме что нибудь сказали...
GDI+ отстой?
← →
Рамиль © (2007-11-12 13:42) [15]Ну... такой вывод я и сам могу сделать:) мне б что нить поконструктивнее.
Хотя бы ответить на
> Рамиль © (07.11.07 09:26) [9]
на pinvoke.net нет этой функции.
← →
antonn © (2007-11-12 14:21) [16]ну все таки ГДИ+ позволяет, особо не заморачиваясь, выводить линии и текст с антиалиасингом, пускай и относительно медленно :)
← →
Algol (2007-11-12 14:27) [17]
> Ну... такой вывод я и сам могу сделать:) мне б что нить
> поконструктивнее.
Касаемо сабжа, то кроме как криворукостью индийского программера, действительно, объяснить эффект сложно.
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.005 c