Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.06.28;
Скачать: CL | DM;

Вниз

Аффинное преобразование 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 передается NativeMatrix
IL_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 вся ветка

Текущий архив: 2009.06.28;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.014 c
15-1240248508
Маэстро
2009-04-20 21:28
2009.06.28
Никто не сталкивался с такой проблемой в WebMoney Keeper?


15-1240342188
StriderMan
2009-04-21 23:29
2009.06.28
VSS plus


15-1240258714
Интересующийся
2009-04-21 00:18
2009.06.28
Структура провайдера


15-1240605003
Юрий
2009-04-25 00:30
2009.06.28
С днем рождения ! 25 апреля 2009 суббота


9-1152026361
Frol
2006-07-04 19:19
2009.06.28
математический маятник