Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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 передается 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 вся ветка

Форум: "Media";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.005 c
4-1211700081
LightRipple
2008-05-25 11:21
2009.06.28
OPEN_IF для секции


15-1240308823
MsGuns
2009-04-21 14:13
2009.06.28
Братцы, что а беспредел в "Базах" !!!!


6-1204126047
rar
2008-02-27 18:27
2009.06.28
IdFTP


15-1239973652
Real
2009-04-17 17:07
2009.06.28
Backup - кто чем пользуется


2-1241715270
Forsted
2009-05-07 20:54
2009.06.28
сброс таймера





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский