Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 | 3 | 4 | 5 |

 

  Вопрос: АПИ в VB6 быстрее... (?) Добавлено: 31.12.06 15:13  

Автор вопроса:  -АлександР- | Web-сайт: sham.clan.su
Привет всем!

Ситуация вынудила сделать опыт по сравнению скорости рисования методами АПИ в вб6 и их аналогами в вб.нет

Судите сами:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim d As Integer = System.Environment.TickCount
        Dim f As Int32

        For f = 1 To 10000
            Dim s As System.Drawing.Graphics = Me.CreateGraphics
            s.DrawLine(Pens.Black, 0, 0, 100, 100)
            s.Dispose()
        Next f

        MsgBox(CStr(System.Environment.TickCount - d))
    End Sub
End Class

выбивает (у меня) до 1235 милисекунд

Аналог на вб6 (через АПИ):
Option Explicit

Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As Long

Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long

Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long

Private Type POINTAPI
        x As Long
        y As Long
End Type

Private Sub Command1_Click()
    Dim s As Long
    s = GetTickCount
    
    Dim i As Integer
    For i = 1 To 10000
        Dim d As Long
        Dim dd As Long
        Dim p As POINTAPI
        p.x = 0
        p.y = 0
        
        d = CreatePen(0, 1, 0)
        dd = SelectObject(hdc, d)
        
        MoveToEx hdc, p.x, p.y, p
        LineTo hdc, 100, 100
        
        d = SelectObject(hdc, dd)
        DeleteObject (d)
    Next i
    
    MsgBox GetTickCount - s
    
End Sub
ОГОГО - за 31 сек. о:)

Получается, что вб6 рисует в десятк раз быстрее...

Что скажут на это защитники .Net.

Объективна ли моя оценка?

Всем ответившим - заранее спасибо

Ответить

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

Номер ответа: 1
Автор ответа:
 Sacred Phoenix



ICQ: 304238252 

Вопросов: 52
Ответов: 927
 Профиль | | #1 Добавлено: 31.12.06 17:52
ИМХО,

1. В VB.NET куча функций-оберток API. То бишь если залезть в дизасм каким-нить Reflector'ом, то выяснится, что многое сходится к API.

2. VB.NET с графикой не дружит

Ответить

Номер ответа: 2
Автор ответа:
 Sacred Phoenix



ICQ: 304238252 

Вопросов: 52
Ответов: 927
 Профиль | | #2 Добавлено: 31.12.06 18:00
Блин, тада уж

Public Class Form1
   Dim s As System.Drawing.Graphics

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      With New Diagnostics.Stopwatch
         .Start()

         For f As Long = 1 To 10000
            s.DrawLine(Pens.Black, 0, 0, 100, 100)
         Next

         .Stop()
         MessageBox.Show(CStr(.ElapsedMilliseconds))
      End With
   End Sub

   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      s = Me.CreateGraphics()
   End Sub
End Class

Рез-ты:
1 вызов: 1065 мс
2 вызов: 911 мс

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #3
Добавлено: 31.12.06 19:30
Рез-ты:
1 вызов: 1065 мс
2 вызов: 911 мс
Я может не внимательный...
но в коде я увидел только одну процедуру измерения.
А с чем сравнивается?

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #4
Добавлено: 31.12.06 19:58
А с чем сравнивается?
А, дошло

Кстати, С++ Builder бъется все рекорды:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        int c = GetTickCount();

        for (int i=1; i < 10000 ;i++)
        {
                Canvas->Pen->Color = 0;
                Canvas->MoveTo(0,0);
                Canvas->LineTo(100,100);
        }

        Button1->Caption =  GetTickCount() - c;
}
15мс (иногда 16)

К сожалению без АПИ, не умею на С++ пользоваться hdc :(
ламер пока...

Ответить

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



Вопросов: 0
Ответов: 1876


 Профиль | | #5 Добавлено: 31.12.06 20:14
ламер пока...

Тогда не надо браться за сравнения, может получиться совсем не то, что собиралось сравниваться.

Сравнил GDI с GDI+. Молодец. Сравни теперь кофеварку с холодильником: кто быстрее? Правильно, утюг.

Причём я почему-то уверен, что ты ещё и в режиме debug vb.net тестировал.
А создание контекста в цикле заново 1000 раз - это вообще шедевр.

GDI+ медленнее GDI раз в 20, и это общеизвестно. Потому что в GDI+ гораздо больше возможностей. И потому что он проектировался с прицелом на аппаратное ускорение, которое пока не реализовано. Реализуют - всё будет наоборот.

Ответить

Номер ответа: 6
Автор ответа:
 Sacred Phoenix



ICQ: 304238252 

Вопросов: 52
Ответов: 927
 Профиль | | #6 Добавлено: 31.12.06 20:31
GDI+ медленнее GDI раз в 20, и это общеизвестно.
ну да, поэтому vb.net с графикой не дружит

Сравни теперь кофеварку с холодильником: кто быстрее? Правильно, утюг.
:D :D :D

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #7
Добавлено: 31.12.06 20:34
Не так все плохо, строгий модер вбстрита :)
Причём я почему-то уверен, что ты ещё и в режиме debug vb.net тестировал.
А создание контекста в цикле заново 1000 раз - это вообще шедевр.
Так и надо. Потому что в вб.нет s.DrawLine(Pens.Black, 0, 0, 100, 100) - это делается за кадром каждый раз... - чтобы объявить цвет. Кроме того и с этим объявлением, оно выдает те же самые результаты...

GDI+ медленнее GDI раз в 20, и это общеизвестно.
В 20-25, если быть точнее. Именно такие результаты я и получил:

Private Sub Command1_Click()
    Dim s As Long
    s = GetTickCount
     
    Dim i As Integer
    For i = 1 To 10000
        Line(0,0)-(100,100),0
    Next i
     
    MsgBox GetTickCount - s
     
End Sub
Результат - 47мс
1235/47=26
вот тык :)

Потому что в GDI+ гораздо больше возможностей. И потому что он проектировался с прицелом на аппаратное ускорение, которое пока не реализовано. Реализуют - всё будет наоборот.
Поскорей бы...
 Это приятная новость :)

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #8
Добавлено: 31.12.06 20:39
Потому что в GDI+ гораздо больше возможностей.
А насчет возможностей, где же они прячутся?
Я что-то не одной не заметил.
Наверно не просто ламер, да еще слепой...
ИМХО все то, что в вб.нет не что иное, как красивое использование АПИ и укомплектование их качесв в одну функцию.

Кто-нибудь назовет хотя бы одну новую граф. возможность, которая реализована вб.нет???

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #9
Добавлено: 31.12.06 20:41
1. В VB.NET куча функций-оберток API. То бишь если залезть в дизасм каким-нить Reflector'ом, то выяснится, что многое сходится к API.
ИМХО Sacred Phoenix верно сказал + АПИ медленнее работают здесь -> вот и тормоз

Ответить

Номер ответа: 10
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #10 Добавлено: 31.12.06 20:53
А насчет возможностей, где же они прячутся?
Я что-то не одной не заметил.

Координты с плавающей точкой.
Сглаживание aka антиалиасинг.
Трансформация.
Новые кисти.
Поддержка загрузки и сохранения в разные графические форматы.
До кучи всякой шняги ещё.

ИМХО Sacred Phoenix верно сказал + АПИ медленнее работают здесь -> вот и тормоз

Sacred Phoenix сказал неверно. API в VB6 вызываются так же медленно.

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #11
Добавлено: 31.12.06 20:56
Sacred Phoenix сказал неверно. API в VB6 вызываются так же медленно.
Мы делали сравнение: http://www.vbnet.ru/forum/show.aspx?id=122982, а на чем основаны ваши утверждения? :)

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #12
Добавлено: 31.12.06 21:00
Координты с плавающей точкой.

Трансформация.
А что это?

Ответить

Номер ответа: 13
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #13 Добавлено: 31.12.06 21:05
Мы делали сравнение: http://www.vbnet.ru/forum/show.aspx?id=122982

По этой ссылке нет сравнения. По этой ссылке размышления о жизни.

Координты с плавающей точкой.

Это тип single в координатах и возможность рисовать с половины пикселя.

Трансформация.

Повороты, наклоны, аффинное преобразование, короче, любое линейное преобразование, которое можно выразить матрицей перехода.

Ответить

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



Вопросов: 55
Ответов: 1008
 Web-сайт: sham.clan.su
 Профиль | | #14
Добавлено: 31.12.06 21:22

По этой ссылке нет сравнения. По этой ссылке размышления о жизни.
Ладно, тогда так:

Option Explicit
Dim pointsArray(0 To 1) As POINTAPI
Private Declare Function GetTickCount Lib "kernel32" () As Long


Private Sub Command1_Click()
    Dim tim As Long
    tim = GetTickCount
    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 + 1
                  
                 Dim CHdc As Long
                 CHdc = CreateRectRgn(pointsArray(0).X, pointsArray(0).Y, _
                 pointsArray(1).X, pointsArray(1).Y)
                 InvertRgn hdc, CHdc
                  
                 ;DeleteObject CHdc
            End If
        Next Y
    Next X
     
    MsgBox GetTickCount - tim
End Sub

860мс
и
Option Strict On
Option Explicit On


Public Class Form1
    Dim pointsArray(1) As POINTAPI
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim Start As Integer = System.Environment.TickCount

        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 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 + 1


                    'CHdc = CreatePolygonRgn(pointsArray(0), 4, ALTERNATE)
                    CHdc = CreateRectRgn(pointsArray(0).X, pointsArray(0).Y, pointsArray(1).X, pointsArray(1).Y)
                    InvertRgn(hdc, CHdc)
                    ;DeleteObject(CHdc)
                End If
            Next Y
        Next X
        myLine.ReleaseHdc()
        MsgBox(System.Environment.TickCount - Start)

    End Sub
End Class

2156мс

Ответить

Номер ответа: 15
Автор ответа:
 GSerg



Вопросов: 0
Ответов: 1876


 Профиль | | #15 Добавлено: 31.12.06 21:45
Приведённый тобой код в VB .NET просто не скомпилируется (хотя бы из-за функции myLine.ReleaseHdc, которая имеет несколько другую сигнатуру).

VB6, откомпилированное. 922 мс.
Option Explicit

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function CreateRectRgn Lib "gdi32.dll" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function InvertRgn Lib "gdi32.dll" (ByVal hdc As Long, ByVal hRgn As Long) As Long
Private Declare Function GetPixel Lib "gdi32.dll" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long

Private Type POINTAPI
  x As Long
  y As Long
End Type

Dim pointsArray(0 To 1) As POINTAPI

Private Sub Command1_Click()
    Dim tim As Long
    tim = GetTickCount
    
    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 + 1
                   
                 Dim CHdc As Long
                 CHdc = CreateRectRgn(pointsArray(0).x, pointsArray(0).y, _
                 pointsArray(1).x, pointsArray(1).y)
                 
                 InvertRgn hdc, CHdc
                   
                 ;DeleteObject CHdc
            End If
        Next
    Next
      
    MsgBox GetTickCount - tim
End Sub



VB .NET 2003, откомпилированное в конфигурации Release: 796 мс.
  Private Declare Function CreateRectRgn Lib "gdi32.dll" (ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer
  Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Integer) As Integer
  Private Declare Function InvertRgn Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal hRgn As Integer) As Integer
  Private Declare Function GetPixel Lib "gdi32.dll" (ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer) As Integer


  <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential, pack:=1)> _
  Private Structure POINTAPI
    Public x As Integer
    Public y As Integer
  End Structure


  Dim pointsArray(1) As POINTAPI


  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim Start As Integer = System.Environment.TickCount

    Dim myLine As System.Drawing.Graphics = 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 Integer = Me.Height
    Dim W As Integer = Me.Width

    Dim hdc As IntPtr = myLine.GetHdc

    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 + 1

          CHdc = CreateRectRgn(pointsArray(0).x, pointsArray(0).y, pointsArray(1).x, pointsArray(1).y)

          InvertRgn(hdc, CHdc)

          ;DeleteObject(CHdc)
        End If
      Next Y
    Next X

    Start = System.Environment.TickCount - Start


    myLine.ReleaseHdc(hdc)
    myLine.Dispose()

    MsgBox(Start)

  End Sub

Ответить

Страница: 1 | 2 | 3 | 4 | 5 |

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



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