Автор вопроса: -АлександР- | 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 рисует в десятк раз быстрее...
Тогда не надо браться за сравнения, может получиться совсем не то, что собиралось сравниваться.
Сравнил GDI с GDI+. Молодец. Сравни теперь кофеварку с холодильником: кто быстрее? Правильно, утюг.
Причём я почему-то уверен, что ты ещё и в режиме debug vb.net тестировал.
А создание контекста в цикле заново 1000 раз - это вообще шедевр.
GDI+ медленнее GDI раз в 20, и это общеизвестно. Потому что в GDI+ гораздо больше возможностей. И потому что он проектировался с прицелом на аппаратное ускорение, которое пока не реализовано. Реализуют - всё будет наоборот.
Причём я почему-то уверен, что ты ещё и в режиме 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+ гораздо больше возможностей. И потому что он проектировался с прицелом на аппаратное ускорение, которое пока не реализовано. Реализуют - всё будет наоборот.
А насчет возможностей, где же они прячутся?
Я что-то не одной не заметил.
Наверно не просто ламер, да еще слепой...
ИМХО все то, что в вб.нет не что иное, как красивое использование АПИ и укомплектование их качесв в одну функцию.
Кто-нибудь назовет хотя бы одну новую граф. возможность, которая реализована вб.нет???
А насчет возможностей, где же они прячутся?
Я что-то не одной не заметил.
Координты с плавающей точкой.
Сглаживание aka антиалиасинг.
Трансформация.
Новые кисти.
Поддержка загрузки и сохранения в разные графические форматы.
До кучи всякой шняги ещё.
ИМХО Sacred Phoenix верно сказал + АПИ медленнее работают здесь -> вот и тормоз
Sacred Phoenix сказал неверно. API в VB6 вызываются так же медленно.
По этой ссылке нет сравнения. По этой ссылке размышления о жизни.
Ладно, тогда так:
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
 eleteObject 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)
 eleteObject(CHdc)
End If
Next Y
Next X
myLine.ReleaseHdc()
MsgBox(System.Environment.TickCount - Start)
Приведённый тобой код в 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
 eleteObject 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
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