Автор вопроса: -АлександР- | Web-сайт:sham.clan.su
Я здесь статью нашел
http://www.gotdotnet.ru/LearnDotNet/VBNET/725.aspx
про переменные Integer в VB.Net, согласно ей (см. таблицу сравнения скорости действия переменных в цикле) должны работать в цикле в 70 раз быстрее, чем в VB6.
Здесь у меня теория расходится с практикой: я написал программу на vb6, которая меня не устраивала по скорости, достаточно медленно... на VB.Net я думал, она будет работать нормально... но она оказалась медленнее раза в 3 !?!?!?!?!?!?!?!
Option Explicit
Dim pointsArray(0 To 3) As POINTAPI
Private Sub Command1_Click()
Line (0, 0)-(100, 100)
Line (0, 0)-(1000, 100), vbBlue
Dim X As Long, Y As Long
For X = 0 To Me.Width / 15
For Y = 0 To Me.Height / 15
If GetPixel(Me.hdc, X, Y) = 0 Then
pointsArray(0).X = X: pointsArray(0).Y = Y
pointsArray(1).X = X + 1: pointsArray(1).Y = Y
pointsArray(2).X = X + 1: pointsArray(2).Y = Y + 1
pointsArray(3).X = X: pointsArray(3).Y = Y + 1
Dim CHdc As Long
'CHdc = CreatePolygonRgn(pointsArray(0), 4, ALTERNATE)
CHdc = CreateRectRgn(pointsArray(0).X, pointsArray(0).Y, _
pointsArray(2).X, pointsArray(2).Y)
InvertRgn hdc, CHdc
DeleteObject CHdc
End If
Next Y
Next X
MsgBox "Есть"
End Sub
Обновил в мастере до
Option Strict Off
Option Explicit On
Friend Class Form1
Inherits System.Windows.Forms.Form
Dim pointsArray(3) As POINTAPI
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click
Dim myLine As System.Drawing.Graphics
myLine = Me.CreateGraphics
myLine.DrawLine(Pens.Black, 0, 0, 200, 200)
myLine.DrawLine(Pens.Blue, 0, 0, 500, 200)
myLine.Dispose()
Dim X, Y As Integer
Dim CHdc As Integer
Dim H As System.Int32 = Me.Height
Dim W As System.Int32 = Me.Width
'Dim d As System.Int32
'd = Me.Width
For X = 0 To W
For Y = 0 To H
If GetPixel(Me.Handle.ToInt32, X, Y) = 0 Then
pointsArray(0).X = X : pointsArray(0).Y = Y
pointsArray(1).X = X + 1 : pointsArray(1).Y = Y
pointsArray(2).X = X + 1 : pointsArray(2).Y = Y + 1
pointsArray(3).X = X : pointsArray(3).Y = Y + 1
Ну в принципе, это я привел для наглядности. Там ещё в модуле разумеется объяв переменных... не важно, но если есть желание можете сравнить сами:
Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
'инвертирует пиксели
Declare Function InvertRgn Lib "gdi32" (ByVal hdc As Long, ByVal hRgn As Long) As Long
'освобождает ненужные ресурсы
Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
'для увеличения скорости взятия цвета
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal nXPos As Long, ByVal nYPos As Long) As Long
Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long) As Long
'тип для хранения массива точек
Type POINTAPI
X As Long
Y As Long
End Type
И в VB.Net:
Declare Function CreateRectRgn Lib "gdi32" (ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer
'инвертирует пиксели
Declare Function InvertRgn Lib "gdi32" (ByVal hdc As Integer, ByVal hRgn As Integer) As Integer
'освобождает ненужные ресурсы
Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Integer) As Integer
'для увеличения скорости взятия цвета
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal nXPos As Integer, ByVal nYPos As Integer) As Integer
Declare Function SetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal crColor As Integer) As Integer
'тип для хранения массива точек
Structure POINTAPI
Dim X As Integer
Dim Y As Integer
End Structure
Выскакивание msgbox'а показывает, когда закончился цикл.
Еще недавно Brand писал, что .Net по скорости в мат. операциях обогнал С++.
Где? По-моему, за шестеркой отстает.
Кто-нибудь может это прокомментировать? Может быть, я сделал поспешные выводы и просто не умею использовать ту мощь, которая в .Net заложена????
Прошу, помогите разобраться
Заранее спасибо ответившим
Ну вобщем-то в твоем примере никакой математики я не вижу, поэтому сравнивать на нем быстродействие математических операций в VB6 и VB .NET нельзя.
Все что я здесь вижу - это вызовы АПИ.
Это может работать медленнее чем в VB6 по причине того что все вызовы АПИ в дотнете выполняются через COM Interop, больше возможных причин для тормозов я не вижу никаких.
Что бы я посоветовал - использовать встроеные управляемые классы GDI+ (они лежат в System.Drawing) - скорости это не прибавит а вот код станет понятнее.
Второе - тебя не насторожило то что твой пример вообще не работает? Как можно проводить анализ быстродействия неработающего примера?
Me.Handle возвращает идентификатор окна (hwnd) и использовать его при выполнении графических идентификатов нельзя - там нужно использовать идентификаторы графического контекста устройств - hdc.
Получить hdc можно с помощью Graphics.GetHDC (сам класс Graphics является представлением графического контекста в библиотеке классов).
После исправления ошибки код работает в 2 раза больше чем до этого
Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Button1.Click
Dim Start As DateTime = Now
Dim myLine As System.Drawing.Graphics
myLine = Me.CreateGraphics
myLine.DrawLine(Pens.Black, 0, 0, 200, 200)
myLine.DrawLine(Pens.Blue, 0, 0, 500, 200)
Dim X, Y As Integer
Dim CHdc As Integer
Dim H As System.Int32 = Me.Height
Dim W As System.Int32 = Me.Width
'Dim d As System.Int32
'd = Me.Width
Dim hdc As Integer = myLine.GetHdc.ToInt32
For X = 0 To W
For Y = 0 To H
If GetPixel(hdc, X, Y) = 0 Then
pointsArray(0).X = X : pointsArray(0).Y = Y
pointsArray(1).X = X + 1 : pointsArray(1).Y = Y
pointsArray(2).X = X + 1 : pointsArray(2).Y = Y + 1
pointsArray(3).X = X : pointsArray(3).Y = Y + 1
'CHdc = CreatePolygonRgn(pointsArray(0), 4, ALTERNATE)
CHdc = CreateRectRgn(pointsArray(0).X, pointsArray(0).Y, pointsArray(2).X, pointsArray(2).Y)
InvertRgn(hdc, CHdc)
 eleteObject(CHdc)
End If
Next Y
Next X
myLine.ReleaseHdc()
MsgBox(Now.Subtract(Start).ToString)
End Sub
А в целом я бы не рекомендовал настолько активно использовать GDI в дотнете - если нужна работа с графикой, то посмотри в сторону MDX или XNA.
Me.Handle возвращает идентификатор окна (hwnd) и использовать его при выполнении графических идентификатов нельзя - там нужно использовать идентификаторы графического контекста устройств - hdc.
Получить hdc можно с помощью Graphics.GetHDC (сам класс Graphics является представлением графического контекста в библиотеке классов).
После исправления ошибки код работает в 2 раза больше чем до этого
Спасибо, Brand!
Все объяснил хорошо, я понял )
если нужна работа с графикой, то посмотри в сторону MDX или XNA.
Вот только не пойму при чем здесь MDX.
Назначение языка MDX (Multidimensional Expressions) — предоставить в распоряжение разработчиков средство для более простого и эффективного доступа к многомерным структурам данных. В Microsoft SQL Server 2000 Analysis Services язык MDX используется для формирования запросов и описания алгоритмов получения вычисляемых значений.
Не вижу связь с графикой.
А XNA... спасибо за совет, посмотрю - хотя то, что для разработки игр, настораживает.
Я был настроен все это делать методами gdi/gdi+, а DirectX, OpenGL... и другое для игр... по-моему их даже нельзя будет на принтере распечатать
Получить hdc можно с помощью Graphics.GetHDC (сам класс Graphics является представлением графического контекста в библиотеке классов).
Забыл сказать - чтоб не было глюков, этот HDC после получения нужно "отпустить":
Graphics.ReleaseHDC, чтоб не было утечки ресурсов.
Вот только не пойму при чем здесь MDX.
Managed DirectX
А XNA... спасибо за совет, посмотрю - хотя то, что для разработки игр, настораживает.
Я был настроен все это делать методами gdi/gdi+, а DirectX, OpenGL... и другое для игр... по-моему их даже нельзя будет на принтере распечатать
Ну смотри сам что тебе нужнее - у меня твой пример отрабаывал 6 секунд, аналогичный код на XNA будет выполняться наверное в сотни раз быстрее.
ReleaseHDC "отпускает" полученый HDC.
Dispose конечно тоже нужно вызывать.
Ага, спасибо!
Ну смотри сам что тебе нужнее - у меня твой пример отрабаывал 6 секунд, аналогичный код на XNA будет выполняться наверное в сотни раз быстрее.
А там объекты создавать можно или там ?
Хотя неважно.
Вот что ещё хотел спросить. Насколько я понял, ты хорошо разбираешься в машинном коде, ассемблере... Можно как-нибудь сделать сюда ассемблерную вставку? Непосредственно нельзя - но хоть как-то?
Это ж будет наврно побыстрее XNA?
Не знаю, в XNA вообще все не так как в GDI работает
Вот что ещё хотел спросить. Насколько я понял, ты хорошо разбираешься в машинном коде, ассемблере...
Очень. Умело всем втираю что я хорошо знаю машинный код
Ассемблерная вставка может быть и быстрее будет, но геморою немножко поприбавится
Побыстрее XNA это не будет - пиксельный шейдер и тот же вызов АПИ - это две немного разные вещи
Могу посоветьвать написать на C++ библиотеку которая бы принимала параметры и делала вызовы нужных АПИ функций - наверняка будет быстрее работать. Может в пару раз.