Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Быстродействие??? Добавлено: 18.11.06 18:56  

Автор вопроса:  -АлександР- | 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

                    'CHdc = CreatePolygonRgn(pointsArray(0), 4, ALTERNATE)
                    CHdc = CreateRectRgn(pointsArray(0).X, pointsArray(0).Y, pointsArray(2).X, pointsArray(2).Y)

                    InvertRgn(Me.Handle.ToInt32, CHdc)

                    DeleteObject(CHdc)
                End If
            Next Y
        Next X

MsgBox("Есть")
End Sub
End Class
Ну в принципе, это я привел для наглядности. Там ещё в модуле разумеется объяв переменных... не важно, но если есть желание можете сравнить сами:
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 заложена????
Прошу, помогите разобраться
Заранее спасибо ответившим

Ответить

  Ответы Всего ответов: 9  

Номер ответа: 1
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #1 Добавлено: 18.11.06 21:34
Ну вобщем-то в твоем примере никакой математики я не вижу, поэтому сравнивать на нем быстродействие математических операций в 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)
                    ;DeleteObject(CHdc)
                End If
            Next Y
        Next X
        myLine.ReleaseHdc()
        MsgBox(Now.Subtract(Start).ToString)
    End Sub


А в целом я бы не рекомендовал настолько активно использовать GDI в дотнете - если нужна работа с графикой, то посмотри в сторону MDX или XNA.

Ответить

Номер ответа: 2
Автор ответа:
 -АлександР-



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #2
Добавлено: 19.11.06 19:12
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... и другое для игр... по-моему их даже нельзя будет на принтере распечатать

Ответить

Номер ответа: 3
Автор ответа:
 -АлександР-



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #3
Добавлено: 19.11.06 19:17
DirectX, OpenGL... и другое для игр... по-моему их даже нельзя будет на принтере распечатать
Да и сложнее все это... и ресурсов требует и установки спец. XNA FrameWork... ужас

(прости, конечно)

2Brand, скажи пожалуйста, что значит myLine.ReleaseHdc() , и почему нет dispose?

Ответить

Номер ответа: 4
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #4 Добавлено: 19.11.06 19:21
Получить hdc можно с помощью Graphics.GetHDC (сам класс Graphics является представлением графического контекста в библиотеке классов).

Забыл сказать - чтоб не было глюков, этот HDC после получения нужно "отпустить":
Graphics.ReleaseHDC, чтоб не было утечки ресурсов.

Вот только не пойму при чем здесь MDX.

Managed DirectX :)

А XNA... спасибо за совет, посмотрю - хотя то, что для разработки игр, настораживает.
Я был настроен все это делать методами gdi/gdi+, а DirectX, OpenGL... и другое для игр... по-моему их даже нельзя будет на принтере распечатать

Ну смотри сам что тебе нужнее - у меня твой пример отрабаывал 6 секунд, аналогичный код на XNA будет выполняться наверное в сотни раз быстрее.

Ответить

Номер ответа: 5
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #5 Добавлено: 19.11.06 19:23
2Brand, скажи пожалуйста, что значит myLine.ReleaseHdc() , и почему нет dispose?

ReleaseHDC "отпускает" полученый HDC.
Dispose конечно тоже нужно вызывать.

Ответить

Номер ответа: 6
Автор ответа:
 -АлександР-



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #6
Добавлено: 20.11.06 14:51
ReleaseHDC "отпускает" полученый HDC.
Dispose конечно тоже нужно вызывать.
Ага, спасибо!
Ну смотри сам что тебе нужнее - у меня твой пример отрабаывал 6 секунд, аналогичный код на XNA будет выполняться наверное в сотни раз быстрее.
А там объекты создавать можно или там ?
Хотя неважно.

Вот что ещё хотел спросить. Насколько я понял, ты хорошо разбираешься в машинном коде, ассемблере... Можно как-нибудь сделать сюда ассемблерную вставку? Непосредственно нельзя - но хоть как-то?
Это ж будет наврно побыстрее XNA:)?

Ответить

Номер ответа: 7
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #7 Добавлено: 21.11.06 08:38
А там объекты создавать можно или там ?

Не знаю, в XNA вообще все не так как в GDI работает :)

Вот что ещё хотел спросить. Насколько я понял, ты хорошо разбираешься в машинном коде, ассемблере...

Очень. Умело всем втираю что я хорошо знаю машинный код :)

Ассемблерная вставка может быть и быстрее будет, но геморою немножко поприбавится :)
Побыстрее XNA это не будет - пиксельный шейдер и тот же вызов АПИ - это две немного разные вещи :)

Могу посоветьвать написать на C++ библиотеку которая бы принимала параметры и делала вызовы нужных АПИ функций - наверняка будет быстрее работать. Может в пару раз.

Ответить

Номер ответа: 8
Автор ответа:
 -АлександР-



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #8
Добавлено: 21.11.06 15:12
Побыстрее XNA это не будет
Почему?

пиксельный шейдер и тот же вызов АПИ - это две немного разные вещи :)
Что такое пиксельный шейдер и при чем вызов АПИ?

Ответить

Номер ответа: 9
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #9 Добавлено: 21.11.06 15:32
Что такое пиксельный шейдер и при чем вызов АПИ?

Я сам точно не знаю что это, но полагаю что это программа, которая выполняется на GPU.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам