Xorianator: an Multi Threading hatte ich auch schon gedacht, aber das Memory Management ist nicht immer ganz trivial, deswegen die Threads im FB Forum.
Mal sehen, ob's klappen wird...
Xorianator: an Multi Threading hatte ich auch schon gedacht, aber das Memory Management ist nicht immer ganz trivial, deswegen die Threads im FB Forum.
Mal sehen, ob's klappen wird...
Mal eine ernstgemeinte Frage, was für ein Sinn hat ein Vergleich zwischen Äpfeln (Compiler) und Birnen (Interpreter)?
Nun ja, beides ist Obst. ![]()
Natürlich ist der Vergleich nicht fair, sondern sehr unfair, aber ich wollte nur zeigen, was bei annähernd gleichem Code Aufbaus für ein extremer Unterschied sein kann. Das Ganze relativiert sich ein wenig, wenn viele DLL Calls stattfinden, wo die Ausführungszeit des Aufrufs eher das Problem ist, z.B. bei GDI+ Funktionen, dann ist der Unterschied nicht mehr so krass.
Man könnte AutoIt pimpen, was Andy bereits erwähnte, gewisse Funktionen in ASM, am besten gleich als MMX/SSE, zu coden. Ich wette, dann würde der Unterschied sich wieder relativieren.
Die Frage stellt sich dann, warum "durch die Brust ins Auge"?
Das hat man davon das die AutoIt-Entwickler neue Features hinzufügen und keinen effizienten Code produzieren.
AutoIt ist auch für solche "Spielereien" nicht gemacht worden. ![]()
Leider ist die Au3 Entwicklung eingeschlafen bzw. innovative Ideen wurden abgelehnt. Mal sehen, was da noch kommen wird...
Ich vermute mal gaanz vage und vorsichtig das es daran liegen könnte das AutoIt3 interpretiert und nicht compiliert wird.
Nichtsdestotrotz ist das Verhältnis "Anzahl der Partikel" 25:1 und trotzdem liegt AutoIt weit hinten!
Selbst bei 100.000 Pixel sinkt die FPS nur auf 48 FPS! ![]()
Da ich seit einigen Wochen FreeBasic (FB) lerne, wollte ich AutoIt mit FreeBasic in Bezug auf GDI / GDI+ Geschwindigkeit testen.
Ich weiß, dass dies ein Vergleich David gegen Goliath ist, aber man sieht den krassen Unterschied.
Runde1 -> GDI Particles Mouse Attraction:
FB: 25.000 Partikel @ 1024x768
Au3: 1.000 Partikel @ 800x600.
AU3:
;coded by UEZ build 2016-07-28
;idea taken from http://jsdo.it/FumioNonaka/jQcv
#pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico")
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe /rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#include <GUIConstantsEx.au3>
#include <WinAPIGdi.au3>
#include <WindowsConstants.au3>
AutoItSetOption("MouseCoordMode", 2)
AutoItSetOption("MustDeclareVars", 1)
Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit
Global Const $iW = 800, $iH = 600, $iParticles = 1000, $sTitle = "GDI Particles Mouse Attraction / Particles: " & $iParticles & " / FPS: "
Global $i, $iMouseX = $iW / 2, $iMouseY = $iH / 2
Global $tParticles = DllStructCreate( _
"float x[" & $iParticles & "];" & _
"float y[" & $iParticles & "];" & _
"float vx[" & $iParticles & "];" & _
"float vy[" & $iParticles & "];" & _
"float friction[" & $iParticles & "];" & _
"uint color[" & $iParticles & "]")
For $i = 1 To $iParticles
With $tParticles
.x(($i)) = Random() * $iW
.y(($i)) = Random() * $iH
.friction(($i)) = 0.975
;~ .color(($i)) = 0xFF000000 + Int(Random() * 0xFFFFFF)
.color(($i)) = 0xFFFFFFFF
EndWith
Next
AutoItSetOption("GUIOnEventMode", 1)
GDI_BurstingParticlesAnimation()
AutoItSetOption("GUIOnEventMode", 0)
Func GDI_BurstingParticlesAnimation()
$hGUI = GUICreate($sTitle & "0", $iW, $iH)
Local Const $hDC = _WinAPI_GetDC($hGUI)
Local $pBits, $tBIV5HDR = DllStructCreate($tagBITMAPV5HEADER)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $tagBITMAPV5HEADER = ' & $tagBITMAPV5HEADER & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
With $tBIV5HDR
.bV5Size = DllStructGetSize($tBIV5HDR)
.bV5Width = $iW
.bV5Height = -$iH
.bV5Planes = 1
.bV5BitCount = 32
.bV5Compression = $BI_RGB
.bV5RedMask = 0x00FF0000
.bV5GreenMask = 0x0000FF00
.bV5BlueMask = 0x000000FF
.bV5AlphaMask = 0xFF000000
EndWith
Local Const $hBitmapGDI = _WinAPI_CreateDIBSection($hDC, $tBIV5HDR, $DIB_RGB_COLORS, $pBits)
Global $tBitmap = DllStructCreate("uint px[" & $iW * $iH & "]", $pBits)
Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC)
Local Const $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI)
GUISetState(@SW_SHOW, $hGUI)
$bExit = False
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
AdlibRegister("CalcFPS", 1000)
Local $iX, $iY
Do
_WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $BLACKNESS)
For $i = 1 To $iParticles
MoveParticles(MouseGetPos(0), MouseGetPos(1), $i)
$iX = Int($tParticles.x(($i)))
$iY = Int($tParticles.y(($i))) * $iW
$tBitmap.px(($iY + $iX)) = $tParticles.color(($i)) ;write directly to the bitmap (one pixel)
Next
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $SRCCOPY)
$iFPS += 1
If $bExit Then ExitLoop
Until Not Sleep(10)
_WinAPI_SelectObject($hGfxDC, $hObjOld)
_WinAPI_ReleaseDC($hGUI, $hDC)
_WinAPI_DeleteDC($hGfxDC)
_WinAPI_DeleteObject($hBitmapGDI)
GUIDelete($hGUI)
EndFunc ;==>GDI_BurstingParticlesAnimation
Func _Exit()
$bExit = True
EndFunc ;==>_Exit
Func CalcFPS() ;display FPS
$iShowFPS = $iFPS
$iFPS = 0
WinSetTitle($hGUI, "", $sTitle & $iShowFPS)
EndFunc ;==>CalcFPS
Func MoveParticles($fX, $fY, $iPos, $fSpeed = 100)
Local $_x, $_y, $_vx, $_vy, $fDiffX, $fDiffY, $fSquare, $fRatio, $fAccX, $fAccY
$_x = $tParticles.x(($iPos))
$_y = $tParticles.y(($iPos))
$_vx = $tParticles.vx(($iPos))
$_vy = $tParticles.vy(($iPos))
$fDiffX = $fX - $_x
$fDiffY = $fY - $_y
$fSquare = ($fDiffX * $fDiffX + $fDiffY * $fDiffY)
$fRatio = $fSquare > 0 ? $fSpeed / $fSquare : 0
$fAccX = $fDiffX * $fRatio
$fAccY = $fDiffY * $fRatio
$_vx += $fAccX
$_vy += $fAccY
$_vx *= $tParticles.friction(($iPos))
$_vy *= $tParticles.friction(($iPos))
$_x += $_vx
$_y += $_vy
If $_x < 0 Then $_x += $iW
If $_x > $iW Then $_x -= $iW
If $_y < 0 Then $_y += $iH
If $_y > $iH Then $_y -= $iH
$tParticles.x(($iPos)) = $_x
$tParticles.y(($iPos)) = $_y
$tParticles.vx(($iPos)) = $_vx
$tParticles.vy(($iPos)) = $_vy
EndFunc ;==>MoveParticles
Alles anzeigen
FB:
'coded by UEZ build 2016-07-28
'idea taken from http://jsdo.it/FumioNonaka/jQcv
#include "windows.bi"
#include "fbgfx.bi"
Using FB
Type tParticles
x As Single
y As Single
vx As Single
vy As Single
friction As Single
argb As UInteger
End Type
Dim Shared As ULong iW = 1024, iH = 768, iParticles = 25000
Dim Shared aParticles(0 To iParticles - 1) As tParticles
Sub MoveParticles(fX As Single, fY As Single, iPos As ULong, fSpeed As Single)
Dim As Single _x, _y, _vx, _vy, fDiffX, fDiffY, fSquare, fRatio, fAccX, fAccY
_x = aParticles(iPos).x
_y = aParticles(iPos).y
_vx = aParticles(iPos).vx
_vy = aParticles(iPos).vy
fDiffX = fX - _x
fDiffY = fY - _y
fSquare = (fDiffX * fDiffX + fDiffY * fDiffY)
fRatio = IIf(fSquare > 0, fSpeed / fSquare, 0)
fAccX = fDiffX * fRatio
fAccY = fDiffY * fRatio
_vx += fAccX
_vy += fAccY
_vx *= aParticles(iPos).friction
_vy *= aParticles(iPos).friction
_x += _vx
_y += _vy
If _x < 0 Then _x += iW
If _x > iW Then _x -= iW
If _y < 0 Then _y += iH
If _y > iH Then _y -= iH
aParticles(iPos).x = _x
aParticles(iPos).y = _y
aParticles(iPos).vx = _vx
aParticles(iPos).vy = _vy
End Sub
ScreenControl FB.SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 32
Dim As String sTitle = "GDI Particles Mouse Attraction / Particles: " & iParticles & " / FPS: "
WindowTitle sTitle
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(integer, hHWND))
Dim As HDC hDC = GetDC(hHWND)
Dim As BITMAPV5HEADER tBIV5HDR
tBIV5HDR.bV5Size = SizeOf(BITMAPV5HEADER)
tBIV5HDR.bV5Width = iW
tBIV5HDR.bV5Height = -iH
tBIV5HDR.bV5Planes = 1
tBIV5HDR.bV5BitCount = 32
tBIV5HDR.bV5Compression = BI_RGB
tBIV5HDR.bV5AlphaMask = &hFF000000
tBIV5HDR.bV5RedMask = &h00FF0000
tBIV5HDR.bV5GreenMask = &h0000FF00
tBIV5HDR.bV5BlueMask = &h000000FF
Dim As UInteger Ptr aBits
Dim As HBitmap hBitmapGDI
Dim As HDC hGfxDC
hBitmapGDI = CreateDIBSection(hDC, @tBIV5HDR, DIB_RGB_COLORS, @aBits, NULL, NULL)
hGfxDC = CreateCompatibleDC(hDC)
Var hObjOld = SelectObject(hGfxDC, hBitmapGDI)
Dim evt As EVENT
Dim As ULong iFPS = 0, i, iMPx = iW / 2, iMPy = iH / 2, iPos, iMax = iW * iH - 1
Dim fTimer As Double
For i = 0 To iParticles - 1
aParticles(i).x = Rnd() * iW
aParticles(i).y = Rnd() * iH
aParticles(i).friction = 0.975
aParticles(i).argb = &hFFFFFFFF
Next
fTimer = Timer
Do
BitBlt(hGfxDC, 0, 0, iW, iH, hGfxDC, 0, 0, BLACKNESS)
GetMouse(iMPx, iMPy)
For i = 0 To iParticles - 1
MoveParticles(iMPx, iMPy, i, 100)
iPos = Int(aParticles(i).x) + Int(aParticles(i).y) * iW
If iPos > iMax Then iPos = iMax
aBits[iPos] = aParticles(i).argb
Next
BitBlt(hDC, 0, 0, iW, iH, hGfxDC, 0, 0, SRCCOPY)
If Timer - fTimer > 1 Then
WindowTitle sTitle & iFPS
iFPS = 0
fTimer = Timer
EndIf
iFPS += 1
'If GetKey = 27 Then Exit Do
If (ScreenEvent(@evt)) Then
If evt.type = EVENT_WINDOW_CLOSE Or evt.type = SC_ESCAPE Then
SelectObject(hGfxDC, hObjOld)
ReleaseDC(hHWND, hDC)
DeleteDC(hGfxDC)
DeleteObject(hBitmapGDI)
Exit Do
EndIf
EndIf
Sleep(10)
Loop
Alles anzeigen
Der Code Aufbau sollte in beiden Sprachen relativ identisch sein (GDI). Die Exe starten und mit der Maus auf der GUI hin und her fahren.
Ergebnis:
Autoit @ 1000 Pixel: ~14 FPS
FB @ 25000 Pixel: ~64 FPS (limitiert, da Sleep verwendet wird)
Krass!
Runde2 -> Mandelbrot:
Au3:
;coded by UEZ build 2016-08-04
;idea taken from http://rosettacode.org/wiki/Mandelbrot_set#C.23 / JS version
#AutoIt3Wrapper_Compile_Both=y
#pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico")
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe /rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#include <GUIConstantsEx.au3>
#include <WinAPIGdi.au3>
#include <WindowsConstants.au3>
AutoItSetOption("MouseCoordMode", 2)
AutoItSetOption("MustDeclareVars", 1)
Global $hGUI, $bExit
Global Const $iW = 1000, $iH = 600, $sTitle = "GDI Mandelbrot / Took "
AutoItSetOption("GUIOnEventMode", 1)
Global $iDetails = 100, $iDisplayFrequency = 100
Mandelbrot(-2, 1, -1, 1, $iDetails, $iDisplayFrequency)
AutoItSetOption("GUIOnEventMode", 0)
Func Mandelbrot($xmin, $xmax, $ymin, $ymax, $iterations, $iDisplayFrequency = 100)
$iDisplayFrequency = $iDisplayFrequency < 1 ? 1 : $iDisplayFrequency > $iH / 2 ? $iH / 2 : $iDisplayFrequency
$hGUI = GUICreate($sTitle & "...", $iW, $iH)
Local Const $hDC = _WinAPI_GetDC($hGUI)
Local $pBits, $tBIV5HDR = DllStructCreate($tagBITMAPV5HEADER)
With $tBIV5HDR
.bV5Size = DllStructGetSize($tBIV5HDR)
.bV5Width = $iW
.bV5Height = -$iH
.bV5Planes = 1
.bV5BitCount = 32
.bV5Compression = $BI_BITFIELDS
.bV5RedMask = 0x00FF0000
.bV5GreenMask = 0x0000FF00
.bV5BlueMask = 0x000000FF
.bV5AlphaMask = 0xFF000000
EndWith
Local Const $hBitmapGDI = _WinAPI_CreateDIBSection($hDC, $tBIV5HDR, $DIB_RGB_COLORS, $pBits)
Global $tBitmap = DllStructCreate("uint px[" & $iW * $iH & "]", $pBits)
Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC)
Local Const $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI)
GUISetState(@SW_SHOW, $hGUI)
$bExit = False
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
Local $iX, $iY, $i, $ppos, $c, $x, $y
Local $fEnd, $fTimer = TimerInit()
For $iY = 0 To $iH - 1
For $iX = 0 To $iW - 1
$x = $xmin + ($xmax - $xmin) * $iX / ($iW - 1)
$y = $ymin + ($ymax - $ymin) * $iY / ($iH - 1)
$i = MandelIter($x, $y, $iterations)
$ppos = ($iW * $iY + $iX)
If ($i > $iterations) Then
$tBitmap.px(($ppos)) = 0xFF000000
Else
$c = 3 * Log($i) / Log($iterations - 1.0)
If ($c < 1) Then
$tBitmap.px(($ppos)) = 0xFF000000 + BitShift(Int(255 * $c), -16)
ElseIf ($c < 2) Then
$tBitmap.px(($ppos)) = 0xFF000000 + BitShift(255, -16) + BitShift(Int(255 * ($c - 1)), -8)
Else
$tBitmap.px(($ppos)) = 0xFFFFFF00 + (Int(255 * ($c - 2)))
EndIf
EndIf
Next
If Not Mod($iY, $iDisplayFrequency) Then
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $SRCCOPY)
ConsoleWrite(Round($iY / $iH * 100, 2) & "%" & @CRLF)
EndIf
Next
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $SRCCOPY)
$fEnd = TimerDiff($fTimer)
WinSetTitle($hGUI, "", $sTitle & $fEnd / 1000 & " seconds to render.")
Do
If $bExit Then ExitLoop
Until Not Sleep(100)
_WinAPI_SelectObject($hGfxDC, $hObjOld)
_WinAPI_ReleaseDC($hGUI, $hDC)
_WinAPI_DeleteDC($hGfxDC)
_WinAPI_DeleteObject($hBitmapGDI)
GUIDelete($hGUI)
EndFunc ;==>Mandelbrot
Func _Exit()
$bExit = True
EndFunc ;==>_Exit
Func MandelIter($cx, $cy, $maxIter)
Local $x = 0.0, $y, $xx, $yy, $xy, $i = $maxIter
While ($xx + $yy <= 4 And $i > 0)
$xy = $x * $y
$xx = $x * $x
$yy = $y * $y
$x = $xx - $yy + $cx
$y = $xy + $xy + $cy
$i -= 1
WEnd
Return $maxIter - $i
EndFunc ;==>MandelIter
Alles anzeigen
FB:
'coded by UEZ build 2016-08-04
'idea taken from http://rosettacode.org/wiki/Mandelbrot_set#C.23 / JS version
#include "windows.bi"
#include "fbgfx.bi"
Using FB
Declare Function mandelIter(cx As Single, cy As Single, maxIter As ULong) As ULong
Declare Sub Mandelbrot(xmin As Single, xmax As Single, ymin As Single, ymax As Single, iterations As ULong, iDisplayFrequency As ULong = 100)
Dim As Integer sW, sH
ScreenInfo(sW, sH)
Dim Shared As ULong iW, iH
iW = 1000 'Int(sW * 0.95)
iH = 600 'Int(sH * 0.90)
ScreenControl FB.SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 24
Dim As String sTitle = "GDI Mandelbrot"
WindowTitle sTitle
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(Integer, hHWND))
Dim Shared As HDC hDC
hDC = GetDC(hHWND)
Dim As BITMAPV5HEADER tBIV5HDR
tBIV5HDR.bV5Size = SizeOf(BITMAPV5HEADER)
tBIV5HDR.bV5Width = iW
tBIV5HDR.bV5Height = -iH
tBIV5HDR.bV5Planes = 1
tBIV5HDR.bV5BitCount = 32
tBIV5HDR.bV5Compression = BI_BITFIELDS
tBIV5HDR.bV5AlphaMask = &hFF000000
tBIV5HDR.bV5RedMask = &h00FF0000
tBIV5HDR.bV5GreenMask = &h0000FF00
tBIV5HDR.bV5BlueMask = &h000000FF
Dim Shared As ULong Ptr aBits
Dim As HBitmap hBitmapGDI
Dim Shared As HDC hGfxDC
hBitmapGDI = CreateDIBSection(hDC, @tBIV5HDR, DIB_RGB_COLORS, @aBits, NULL, NULL)
hGfxDC = CreateCompatibleDC(hDC)
Var hObjOld = SelectObject(hGfxDC, hBitmapGDI)
Dim evt As EVENT
Dim As ULong iFPS = 0, i, iMax = iW * iH - 1 , iX, iY, iARGB
Dim As Double fTimer, fEnd
fTimer = Timer
Mandelbrot(-2, 1, -1, 1, 5000, 100)
fEnd = Timer - fTimer
WindowTitle sTitle & " / Took " & fEnd & " seconds to render."
Do
If (ScreenEvent(@evt)) Then
Select Case evt.Type
Case SC_ESCAPE, EVENT_WINDOW_CLOSE
SelectObject(hGfxDC, hObjOld)
ReleaseDC(hHWND, hDC)
DeleteDC(hGfxDC)
DeleteObject(hBitmapGDI)
Exit Do
End Select
EndIf
Sleep(60)
Loop
Sub Mandelbrot(xmin As Single, xmax As Single, ymin As Single, ymax As Single, iterations As ULong, iDisplayFrequency As ULong = 100)
Dim As ULong i, ppos
Dim As Double c, x, y
Dim As ULong iX, iY
For iY = 0 To iH - 1
For iX = 0 To iW - 1
x = xmin + (xmax - xmin) * iX / (iW - 1)
y = ymin + (ymax - ymin) * iY / (iH - 1)
i = mandelIter(x, y, iterations)
ppos = (iW * iY + iX)
If (i > iterations) Then
aBits[ppos] = &hFF000000
Else
c = 3 * Log(i) / Log(iterations - 1.0)
If (c < 1) Then
aBits[ppos] = &hFF000000 + (Int(255 * c) Shl 16)
ElseIf ( c < 2 ) Then
aBits[ppos] = &hFF000000 + (255 Shl 16) + (Int(255 * (c - 1)) Shl 8)
Else
aBits[ppos] = &hFFFFFF00 + (Int(255 * (c - 2)))
EndIf
EndIf
Next
If iY Mod iDisplayFrequency = 0 Then BitBlt(hDC, 0, 0, iW, iH, hGfxDC, 0, 0, SRCCOPY)
Next
BitBlt(hDC, 0, 0, iW, iH, hGfxDC, 0, 0, SRCCOPY)
End Sub
Function mandelIter(cx As Single, cy As Single, maxIter As ULong) As ULong
Dim As Single x = 0.0, y, xx, yy, xy
Dim As ULong i = maxIter
While (xx + yy <= 4 And i > 0)
xy = x * y
xx = x * x
yy = y * y
x = xx - yy + cx
y = xy + xy + cy
i -= 1
Wend
Return maxIter - i
End Function
Alles anzeigen
AU3: ~107 Sekunden @100
FB: ~0.30 Sekunden @100, 1,7s @1000, 7,8s @5000 und 14,6s @10000.
Falls ihr Au3 mit $iDetails = 1000 ausprobieren wollt, dann macht euch vorher einen Kaffee, den ihr langsam und genüsslich trinken könnt oder falls ihr Raucher seid, dann raucht am besten eine dicke fette Zigarre ![]()
Runde3 -> GDI+ Performance Test:
Au3:
;coded by UEZ in 2016-08-05
#AutoIt3Wrapper_Compile_Both=y
#pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico")
#AutoIt3Wrapper_Run_Au3Stripper=y
#Au3Stripper_Parameters=/so /pe /rm
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3"
#include <GDIPlus.au3>
Global Const $iW = 1000, $iH = 600, $sTitle = "GDI+ Performance Test / "
Global Const $hGUI = GUICreate($sTitle, $iW, $iH)
GUISetState()
_GDIPlus_Startup()
Global Const $hCanvas = _GDIPlus_GraphicsCreateFromHWND($hGUI)
_GDIPlus_GraphicsSetSmoothingMode($hCanvas, 4)
Global Const $hPen = _GDIPlus_PenCreate(0xFF000000)
_GDIPlus_GraphicsClear($hCanvas)
Global $i, $fX1, $fY1, $fX2, $fY2, $iRounds = 20000
Global $fEnd, $fTimer = TimerInit()
For $i = 1 To $iRounds
$fX1 = Random() * $iW
$fX2 = Random() * $iW
$fY1 = Random() * $iH
$fY2 = Random() * $iH
_GDIPlus_PenSetColor($hPen, 0xFF000000 + Int(Random() * 0xFFFFFF))
_GDIPlus_GraphicsDrawLine($hCanvas, $fX1, $fY1, $fX2, $fY2, $hPen)
Next
$fEnd = TimerDiff($fTimer)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_Shutdown()
WinSetTitle($hGUI, "", $sTitle & "Created " & $iRounds & " lines in " & Round($fEnd, 2) & " ms.")
Do
Until GUIGetMsg() = -3
Alles anzeigen
FB:
'coded by UEZ in 2016-08-05
#Include "win\gdiplus.bi"
#include "fbgfx.bi"
#include "windows.bi"
Using FB
Using GDIPLUS
Dim Shared As ULong iW, iH
iW = 1000
iH = 600
Dim As String sTitle = "GDI+ Performance Test / "
ScreenControl FB.SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 32
WindowTitle sTitle
Dim evt As EVENT
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(Integer, hHWND))
'_GDIPlus_Startup()
Dim GDIPlusStartupInput As GDIPLUSSTARTUPINPUT
Dim As ULONG_PTR GDIPlusToken
GDIPlusStartupInput.GdiplusVersion = 1
If (GdiplusStartup(@GDIPlusToken, @GDIPlusStartupInput, NULL) <> 0) Then
Print "FAILED TO INIT GDI+!"
EndIf
Dim As Any Ptr hCanvas, hPen
GdipCreateFromHWND(hHWND, @hCanvas) '_GDIPlus_GraphicsCreateFromHWND($hGUI)
GdipSetSmoothingMode(hCanvas, 4) '_GDIPlus_GraphicsSetSmoothingMode($hCanvas, 4)
GdipCreatePen1(&hFF000000, 1, 2, @hPen) '_GDIPlus_PenCreate(0xFF000000)
GdipGraphicsClear(hCanvas, &hFF000000) '_GDIPlus_GraphicsClear($hCanvas)
Dim As Single fX1, fY1, fX2, fY2
Dim As ULong iRounds = 20000, i
Dim As Double fEnd, fTimer
fTimer = Timer 'TimerInit()
For i = 1 To iRounds
fX1 = Rnd() * iW
fX2 = Rnd() * iW
fY1 = Rnd() * iH
fY2 = Rnd() * iH
GdipSetPenColor(hPen, &hFF000000 + Int(Rnd() * &hFFFFFF)) '_GDIPlus_PenSetColor($hPen, 0xFF000000 + Int(Random() * 0xFFFFFF))
GdipDrawLine(hCanvas, hPen, fX1, fY1, fX2, fY2) '_GDIPlus_GraphicsDrawLine($hCanvas, $fX1, $fY1, $fX2, $fY2, $hPen)
Next
fEnd = (Timer - fTimer) * 1000 'TimerDiff($fTimer) -> FB counts in seconds not in ms!
GdipDeletePen(hPen) '_GDIPlus_PenDispose($hPen)
GdipDeleteGraphics(hCanvas) '_GDIPlus_GraphicsDispose($hCanvas)
GdiplusShutdown(GDIPlusToken) '_GDIPlus_Shutdown()
WindowTitle sTitle & "Created " & iRounds & " lines in " & fEnd & " ms."
Do
'something like GUIGetMsg()
If (ScreenEvent(@evt)) Then
Select Case evt.Type
Case SC_ESCAPE, EVENT_WINDOW_CLOSE
Exit Do
End Select
EndIf
Sleep(30)
Loop
Alles anzeigen
Au3: ca. 16,9 Sekunden
FB: ca. 14,5 Sekunden
Im Anhang die Source Codes + kompilierte Exes.
FB gefällt mir immer mehr...
Weitere Bespiele:
Battle GDI vs GDI+: Battle: Autoit vs. FreeBasic - Runde 1+2+3
Animated Pythagoras Tree in GDI / GDI+ / OpenGL: Battle: Autoit vs. FreeBasic - Runde 1+2+3
GDI Particle Repulsion Grid in GDI: Battle: Autoit vs. FreeBasic - Runde 1+2+3
![]()
Schaue mal hier rein: https://www.autoitscript.com/forum/topic/179451-solved-preserve-ascpect-ratio-_gdiplus/?do=findComment&comment=1287798
Vielleicht ist es brauchbar.
Die Zeile einfach auskommentieren und dann sollte es funzen.
Ich hatte vor langer Zeit was gebastelt. Vielleicht kannst was gebrauchen:
Ist seit 2013 nicht mehr weiter entwickelt.
Sorry UEZ, aber ich habe von Fussball so viel Ahnung wie vom Fliegen
Das macht nichts. Man(n) / Frau muss keine Ahnung haben, um Fussball Tipps abzugeben.
Hab ich auch nicht und dann noch verpennt die Tipps nach der Gruppenphase nachzutragen -.-'
Das habe ich gemerkt. ![]()
Gewonnen hat Techmix - herzlichen Glückwunsch!
Das nächste Mal (WM2018) könnten ruhig ein paar mehr mittippen!
Als nächsten Schritt werde ich versuchen die Funktionen erst mal per Threading zu beschleunigen. Mal sehen, ob's klappt und was am Ende rausspringen wird.
Andy: danke für dein Feedback. ![]()
....und dann würdest du so aussehen wie ich
Da fehlt nicht mehr viel. ![]()
Wie gesagt, da ist noch genug Raum für (ASM) Optimierungen.
Da müsste ich erst mal die MMX / SSE Befehle richtig verstehen, damit überhaupt eine Boost erreicht werden kann. Ich glaube nicht, dass mit den Standard ASM Befehlen ich überhaupt was rausholen kann.
Da AutoIt für Bild Effekte / Bildbearbeitung zu langsam ist, wenn die Funktion nicht in der GDIPlus DLL vorhanden sind, habe ich eine DLL mit FreeBasic programmiert, die diese Lücke schließen soll. Natürlich ist Raum für Optimierungen vorhanden!
Folgende Filter sind implementiert:
_GDIPlus_BitmapApplyFilter_BWJJNDithering
_GDIPlus_BitmapApplyFilter_Cartoon1
_GDIPlus_BitmapApplyFilter_ColorAccent
_GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur
_GDIPlus_BitmapApplyFilter_Convolution_BoxBlur
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5
_GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6
_GDIPlus_BitmapApplyFilter_Convolution_Emboss1
_GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree
_GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight
_GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3
_GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1
_GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2
_GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur
_GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss
_GDIPlus_BitmapApplyFilter_Convolution_Kirsch
_GDIPlus_BitmapApplyFilter_Convolution_Laplace1
_GDIPlus_BitmapApplyFilter_Convolution_Laplace2
_GDIPlus_BitmapApplyFilter_Convolution_Laplace3
_GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian
_GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix
_GDIPlus_BitmapApplyFilter_Convolution_MotionBlur
_GDIPlus_BitmapApplyFilter_Convolution_Outline3x3
_GDIPlus_BitmapApplyFilter_Convolution_Prewitt
_GDIPlus_BitmapApplyFilter_Convolution_Sharpen1
_GDIPlus_BitmapApplyFilter_Convolution_Sharpen2
_GDIPlus_BitmapApplyFilter_Convolution_Sobel
_GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt
_GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur
_GDIPlus_BitmapApplyFilter_Convolution_Unsharp
_GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5
_GDIPlus_BitmapApplyFilter_Dilatation
_GDIPlus_BitmapApplyFilter_DistortionBlur
_GDIPlus_BitmapApplyFilter_Edges
_GDIPlus_BitmapApplyFilter_Erosion
_GDIPlus_BitmapApplyFilter_FishEye
_GDIPlus_BitmapApplyFilter_Indexed
_GDIPlus_BitmapApplyFilter_Jitter
_GDIPlus_BitmapApplyFilter_Kuwahara
_GDIPlus_BitmapApplyFilter_Linellism
_GDIPlus_BitmapApplyFilter_Median
_GDIPlus_BitmapApplyFilter_Median2
_GDIPlus_BitmapApplyFilter_OilPainting
_GDIPlus_BitmapApplyFilter_PenSketch
_GDIPlus_BitmapApplyFilter_PenSketch2
_GDIPlus_BitmapApplyFilter_Pixelate
_GDIPlus_BitmapApplyFilter_Pointillism
_GDIPlus_BitmapApplyFilter_RadialBlur
_GDIPlus_BitmapApplyFilter_Raster
_GDIPlus_BitmapApplyFilter_Swirl
_GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour
_GDIPlus_BitmapApplyFilter_TiltShift
_GDIPlus_BitmapApplyFilter_TimeWarp
_GDIPlus_BitmapApplyFilter_Wave
_GDIPlus_BitmapApplyFilter_XRay
Alles anzeigen
Beispiele zu den einzelnen Funktionen kann man in der Zip Dateie finden.
Download und Screenshots hier: https://www.autoitscript.com/forum/files/fi…ilter-udf-beta/
Die Filter in ASM zu implementieren wäre sicherlich eine Herausforderung, aber dann würden mir mit hoher Wahrscheinlichkeit die letzten Haare ausfallen... ![]()
Viel Spaß beim Ausprobieren.
Die neue Version funzt auch ohne Probleme bei mir. DL ~@1600 kb/s.
Beim Starten kommt
Row|Col 0|Col 1|Col 2|Col 3|Col 4|Col 5
[0]|4|||||
[1]|http://download.bleepingcomputer.com/Xplode/AdwCleaner.exe|AdwCleaner.exe|||1|
[2]|http://download.iobit.com/action-center/asc920-0330.exe|Advanced_SystemCare.exe|||2|
[3]|http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe|DrWeb-CureIt.exe|||3|
[4]|http://data-cdn.mbamupdates.com/web/JRT.exe|JRT.exe|||4|
Am Ende kommt kein ArrayDisplay.
Row|Col 0|Col 1|Col 2|Col 3|Col 4|Col 5
[0]|4||182870360|182870360||
[1]|http://download.bleepingcomputer.com/Xplode/AdwCleaner.exe|AdwCleaner.exe|3703360|3703360|Erfolg|
[2]|http://download.iobit.com/action-center/asc920-0330.exe|Advanced_SystemCare.exe|42688424|42688424|Erfolg|
[3]|http://download.geo.drweb.com/pub/drweb/cureit/drweb-cureit.exe|DrWeb-CureIt.exe|134867760|134867760|Erfolg|
[4]|http://data-cdn.mbamupdates.com/web/JRT.exe|JRT.exe|1610816|1610816|Erfolg|
Funzt bei mir ohne Probleme. Für die 178 MB kommt mir die DL Zeit etwas langsam vor.
Deshalb anzeigen:
Wen's interessiert, hier einige Beispiele, um GDI+ mit Hilfe von FreeBasic zu beschleunigen: https://www.autoitscript.com/forum/topic/18…using-freebasic
Insgesamt nur 5 Teilnehmer. ![]()
Bald ist es soweit, also wer noch Lust hast, einfach anmelden (siehe Post#1).
Das hier funzt:
#Include Once "win\gdiplus.bi"
Using GDIPLUS
Extern "Windows-MS"
Sub Boost(ByVal hCanvas as GpGraphics Ptr, ByVal tData As Any Ptr, _
iCountX As UInteger, iCountY As UInteger, _
fX As Single, fY As Single, fZ As Single, fW As Single, fH As Single, fScale As Single) Export
Dim As UInteger c, iUBound, iSingle
Dim As Single Ptr pX, pY, pZ, pfX, pfY, pFZ
Dim As UInteger Ptr pPen
Dim As Single fCosRotX, fSinRotX, fCosRotY, fSinRotY, fCosRotZ, fSinRotZ, f1, f2, f3, f4, f5, f6, fXPos, fYPos, fZPos, fZPerspCorrection, fZDeepCorrection
iUBound = iCountX * iCountY + iCountX + iCountY + 1
iSingle = SizeOf(Single)
fZDeepCorrection = 1000.0
For c = 0 To iUbound - 1
pX = tData '+ 0 * iUBound + 0 * iSingle
pY = tData + 1 * iUBound * iSingle
pZ = tData + 2 * iUBound * iSingle
pfX = tData + 3 * iUBound * iSingle
pfY = tData + 4 * iUBound * iSingle
pfZ = tData + 5 * iUBound * iSingle
pPen = tData + 6 * iUBound * iSingle
fCosRotX = Cos(fX)
fSinRotX = Sin(fX)
fCosRotY = Cos(fY)
fSinRotY = Sin(fY)
fCosRotZ = Cos(fZ)
fSinRotZ = Sin(fZ)
f1 = fCosRotY * pX[c]
f2 = fSinRotX * pY[c]
f3 = fCosRotX * pZ[c]
f4 = fCosRotX * pY[c]
f5 = fSinRotX * pZ[c]
f6 = f1 - fSinRotY * (f2 + f3)
fXPos = (fCosRotZ * f6 - fSinRotZ * (f4 - f5)) * fScale
fYPos = (fSinRotZ * f6 + fCosRotZ * (f4 - f5)) * fScale
fZPos = (fSinRotY * pX[c] + fCosRotY * (f2 + f3)) * fScale
fZPerspCorrection = 1 / (fZPos / fZDeepCorrection + 1)
pfX[c] = fXPos * fZPerspCorrection + fW
pfY[c] = fYPos * fZPerspCorrection + fH
pfZ[c] = fZPos
If c > 0 Then
GdipDrawLine(hCanvas, pPen[c], pfX[c - 1], pfY[c - 1], pfX[c], pfY[c])
EndIf
Next
End Sub
End Extern
Alles anzeigen