jvanegmond Posted February 20, 2009 Share Posted February 20, 2009 (edited) I wrote a short test case, as is customary with these type of issues. Part of the output: Test #20 Loop result: 2432902008176640000 Time: 0.0203936533833211 Recursive result: 2432902008176640000 Time: 0.121523824955406 This shows that recursive is indeed slower. The loop approach is around 6 times faster. The validity of this test is questionable, at best, though.. I've also let it run to 500. The results were wrong , but the time it took to calculate them may still be an indication. All it did was make the test results more obvious. Code to perform the tests: ;; Doing a little test to make sure it works. $s = "Recursive: " & _RecurFac(5) & @CRLF & _ "Loop: " & _LoopFac(5) & @CRLF & _ "Expecting: " & (5*4*3*2*1) & @CRLF ConsoleWrite($s) For $i = 1 to 20 ; 500 $startLoop = TimerInit() $loopRes = _LoopFac($i) $endLoop = TimerDiff($startLoop) $startRecur = TimerInit() $recurRes = _RecurFac($i) $endRecur = TimerDiff($startRecur) ConsoleWrite("Test #" & $i & @CRLF & @TAB & "Loop result: " & $loopRes & " Time: " & $endLoop & @CRLF & @TAB & "Recursive result: " & $recurRes& " Time: " & $endRecur & @CRLF) Next Func _RecurFac($n) If ($n == 0) Then Return 1 Return $n * _RecurFac($n-1) EndFunc Func _LoopFac($n) Local $res = 1 For $i = 1 to $n $res *= $i Next Return $res EndFunc Edited February 20, 2009 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
UEZ Posted February 20, 2009 Author Share Posted February 20, 2009 I made the same test also with factorial but couldn't see any great difference. Maybe a more complicated example (quicksort ) could help to get more about runtime if a relative big text is sorted. If I have enough time I will try to implement quicksort UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
UEZ Posted February 20, 2009 Author Share Posted February 20, 2009 (edited) Here an example with Fibonnaci numbers: $n = 25 $bench_start = TimerInit() ConsoleWrite(Fibonacci_i($n) & @CRLF) $bench_end_i = Round(TimerDiff($bench_start), 4) $bench_start = TimerInit() ConsoleWrite(Fibonacci_r($n) & @CRLF) $bench_end_r = Round(TimerDiff($bench_start), 4) ConsoleWrite(@CRLF & "Iterative: " & $bench_end_i & " ms" & @CRLF & "Recursive: " & $bench_end_r & " ms" & @CRLF & "Diff: " & Abs($bench_end_i - $bench_end_r) & " ms !" & @CRLF & @CRLF) Func Fibonacci_i($f) Dim $arr_fib[3] $arr_fib[0] = 0 $arr_fib[1] = 1 For $i = 2 To $f $arr_fib[2] = $arr_fib[1] + $arr_fib[0] $arr_fib[0] = $arr_fib[1] $arr_fib[1] = $arr_fib[2] Next Return $arr_fib[2] EndFunc Func Fibonacci_r($f) If $f = 0 Then Return 0 If $f = 1 Then Return 1 Return Fibonacci_r($f - 1) + Fibonacci_r($f - 2) EndFunc Output results: CODE75025 75025 Iterative: 2.4656 ms Recursive: 1186.7369 ms Diff: 1184.2713 ms ! Huge difference ! UEZ Edited February 20, 2009 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Valik Posted February 20, 2009 Share Posted February 20, 2009 Function lookups are almost invariably going to be slower than iteration. There's more work under the hood... like looking up a function and calling it. Link to comment Share on other sites More sharing options...
weaponx Posted February 20, 2009 Share Posted February 20, 2009 The issue with the original code has nothing to do with recursion. It's even obvious while its running that the recursion depth is only like 2 but the redraw times are atrocious (half a second). The slowness is because of GDI. That being said, if someone can provide faster method for drawing then I would try that. Link to comment Share on other sites More sharing options...
jvanegmond Posted February 20, 2009 Share Posted February 20, 2009 Function lookups are almost invariably going to be slower than iteration. There's more work under the hood... like looking up a function and calling it.Would you please elaborate on that? I am very interested in how AutoIt works "under the hook" in this particular instance. github.com/jvanegmond Link to comment Share on other sites More sharing options...
weaponx Posted February 20, 2009 Share Posted February 20, 2009 (edited) Would you please elaborate on that? I am very interested in how AutoIt works "under the hook" in this particular instance.http://www.autoitscript.com/forum/index.php?showtopic=70777 Edited February 20, 2009 by weaponx Link to comment Share on other sites More sharing options...
UEZ Posted February 20, 2009 Author Share Posted February 20, 2009 The issue with the original code has nothing to do with recursion. It's even obvious while its running that the recursion depth is only like 2 but the redraw times are atrocious (half a second). The slowness is because of GDI. That being said, if someone can provide faster method for drawing then I would try that. How to you measure the GDI+ drawing? I modified it the code from my 12th post: expandcollapse popup#include Opt('MustDeclareVars', 1) Global Const $Pi = 3.1415926535897932384626 Global Const $width = 800 Global Const $height = 600 Global $hGUI, $hGraphic, $Pen Global $angle = 0, $x1, $y1, $x2, $y2 Global $length, $depth, $dir, $degree, $dist_rel, $average = 0, $c = 0 $hGUI = GUICreate("GDI+: L-System Fractals by UEZ 2009", $width, $height) GUISetState() _GDIPlus_Startup () $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI) $Pen = _GDIPlus_PenCreate(0, 1) ; create a pen to use later on _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 4) ; AntiAlias _GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF) $x1 = $width / 2 $y1 = $height / 1.1 $length = 110 $depth = 10 $dir = 1 $angle = 5 Pythagoras($length, $depth, $dir) ConsoleWrite(@CRLF & "Average: " & Round ($average / $c, 2) & " ms." & @CRLF) Sleep(1000 * 10) _Exit() Func Pythagoras($length, $split, $dir) If $split = 0 Then Pythagoras_Square($length) Else $dist_rel = Sqrt(3) / 2 $degree = 30 Pythagoras_Square($length) Forward_Only($length) Turn(-$dir * 1 * $degree) Pythagoras($length * $dist_rel, $split - 1, 1) Turn($dir * 3 * $degree) Forward_Only($length * $dist_rel) Pythagoras($length / 2, $split - 1, 1) Forward_Only(-$length * $dist_rel) Turn(-$dir * 2 * $degree) Forward_Only(-$length) EndIf Sleep(1) EndFunc Func Pythagoras_Square($length) Local $i For $i = 1 To 4 Draw_and_Forward($length) Turn($dir * 90) Next EndFunc Func Turn ($degrees) $angle = $angle + ($degrees * $Pi / 180) EndFunc Func Draw_and_Forward($length) Local $bench_start = TimerInit() $x2 = $x1 + Cos($angle) * $length $y2 = $y1 + Sin($angle) * $length _GDIPlus_PenSetColor($Pen, "0x7F000000") ;Set the pen color _GDIPlus_GraphicsDrawLine($hGraphic, $x1, $y1, $x2, $y2, $Pen) $x1 = $x2 $y1 = $y2 Local $bench_end = TimerDiff($bench_start) ;~ ConsoleWrite(Round($bench_end, 4) & @CRLF) $average += $bench_end $c += 1 EndFunc Func Forward_Only($length) $x2 = $x1 + Cos($angle) * $length $y2 = $y1 + Sin($angle) * $length $x1 = $x2 $y1 = $y2 EndFunc Func _Exit() ; Clean up resources _GDIPlus_PenDispose($Pen) _GDIPlus_GraphicsDispose ($hGraphic) _GDIPlus_Shutdown () Exit EndFuncoÝ÷ Ù¬º[[÷«j´Û¬2>v¶°x?mhv¶°x+axºÚ"µÍÚ[ÛYH ÑÑTË]LÉÝÂÜ ÌÎNÓ]ÝXÛUÉÌÎNËJBÛØ[ÛÛÝ ÌÍÔHHËMMNLLÍNMÎLÌÎ ÛØ[ÛÛÝ ÌÍÝÚYHÛØ[ÛÛÝ ÌÍÚZYÚH ÛØ[ ÌÍÚÕRK ÌÍÚÜXË ÌÍÔ[ÛØ[ ÌÍØ[ÛHH ÌÍÞK ÌÍÞLK ÌÍÞ ÌÍÞLÛØ[ ÌÍÛ[Ý ÌÍÙ ÌÍÙ ÌÍÙYÜYK ÌÍÙÝÜ[ ÌÍØ]YÙHH ÌÍØÈHß ÌÍÚÕRHHÕRPÜX]J ][ÝÑÑJÎTÞÝ[HXÝ[ÈHQVI][ÝË ÌÍÝÚY ÌÍÚZYÚ BßÕRTÙ]Ý]J BßÑÑT×ÔÝ Bß ÌÍÚÜXÈHÑÑT×ÑÜXÜÐÜX]QÛRÓ ÌÍÚÕRJBß ÌÍÔ[HÑÑT×Ô[ÜX]JJHÈÜX]HH[ÈÙH]ÛßÑÑT×ÑÜXÜÔÙ]Û[ÛÝ[Ó[ÙJ ÌÍÚÜXË HÈ[P[XÂßÑÑT×ÑÜXÜÐÛX ÌÍÚÜXËBÌÍÞHH ÌÍÝÚYÈÌÍÞLHH ÌÍÚZYÚÈKBÌÍÛ[ÝHLLÌÍÙHLÌÍÙHBÌÍØ[ÛHH BÛØ[ ÌÍØ[ÚÜÝH[Y[] B]YÛÜÊ ÌÍÛ[Ý ÌÍÙ ÌÍÙBÛØ[ ÌÍØ[ÚÙ[H[YY ÌÍØ[ÚÜÝ BÛÛÛÛUÜ]JÔ [È ][ÝÔ[[YN ][ÝÈ [ÈÝ[ ÌÍØ[ÚÙ[ÈL H [È ][ÝÈÙXÛÛË][ÝÈ [ÈÔBÛY L L BÑ^] B[È]YÛÜÊ ÌÍÛ[Ý ÌÍÜÜ] ÌÍÙBY ÌÍÜÜ]H[]YÛÜ×ÔÜ]XJ ÌÍÛ[Ý B[ÙB ÌÍÙÝÜ[HÜ ÊHÈ ÌÍÙYÜYHHÌ]YÛÜ×ÔÜ]XJ ÌÍÛ[Ý BÜØÓÛJ ÌÍÛ[Ý BIÌÍÙ H ÌÍÙYÜYJB]YÛÜÊ ÌÍÛ[Ý ÌÍÙÝÜ[ ÌÍÜÜ]HKJB ÌÍÙ È ÌÍÙYÜYJBÜØÓÛJ ÌÍÛ[Ý ÌÍÙÝÜ[ B]YÛÜÊ ÌÍÛ[ÝÈ ÌÍÜÜ]HKJBÜØÓÛJIÌÍÛ[Ý ÌÍÙÝÜ[ BIÌÍÙ ÌÍÙYÜYJBÜØÓÛJIÌÍÛ[Ý B[YÛY JB[[Â[È]YÛÜ×ÔÜ]XJ ÌÍÛ[Ý BØØ[ ÌÍÚBÜ ÌÍÚHHHÈ ]×Ø[ÑÜØ ÌÍÛ[Ý B ÌÍÙ L B^[[Â[È ÌÍÙYÜYÊB ÌÍØ[ÛHH ÌÍØ[ÛH È ÌÍÙYÜYÈ ÌÍÔHÈN B[[Â[È]×Ø[ÑÜØ ÌÍÛ[Ý B ÌÍÞH ÌÍÞH ÈÛÜÊ ÌÍØ[ÛJH ÌÍÛ[Ý ÌÍÞLH ÌÍÞLH ÈÚ[ ÌÍØ[ÛJH ÌÍÛ[ÝßÑÑT×Ô[Ù]ÛÛÜ ÌÍÔ[ ][ÝÌ Ñ ][ÝÊHÔÙ]H[ÛÛÜßÑÑT×ÑÜXÜÑ]Ó[J ÌÍÚÜXË ÌÍÞK ÌÍÞLK ÌÍÞ ÌÍÞL ÌÍÔ[B ÌÍÞHH ÌÍÞ ÌÍÞLHH ÌÍÞL[[Â[ÈÜØÓÛJ ÌÍÛ[Ý B ÌÍÞH ÌÍÞH ÈÛÜÊ ÌÍØ[ÛJH ÌÍÛ[Ý ÌÍÞLH ÌÍÞLH ÈÚ[ ÌÍØ[ÛJH ÌÍÛ[Ý ÌÍÞHH ÌÍÞ ÌÍÞLHH ÌÍÞL[[Â[ÈÑ^] BÈÛX[ÛÝÙÂßÑÑT×Ô[ÜÜÙJ ÌÍÔ[BßÑÑT×ÑÜXÜÑÜÜÙH ÌÍÚÜXÊBßÑÑT×ÔÚ]ÝÛ B^][[ If I compare the GDI+ drawing time against without drawing GDI+: Without GDI+ drawing: Runtime: 31.9456 seconds. With GDI+ drawing: Runtime: 31.9378 seconds. My conclusion: I cannot agree what you said! Fibonacci numbers is also a proof that recursion is the problem in AutoIt (mentioned by Valik in post #24). If I can find time I will try to implement one of the L-System example to an iterative version. I bet it would be much faster... UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Valik Posted February 20, 2009 Share Posted February 20, 2009 Would you please elaborate on that? I am very interested in how AutoIt works "under the hook" in this particular instance.It's irrelevant, it's an implementation detail. It's subject to change and off the top of my head I'm not sure exactly what we're doing at the moment. Link to comment Share on other sites More sharing options...
weaponx Posted February 20, 2009 Share Posted February 20, 2009 If I compare the GDI+ drawing time against without drawing GDI+:Without GDI+ drawing: Runtime: 31.9456 seconds.With GDI+ drawing: Runtime: 31.9378 seconds.My conclusion: I cannot agree what you said! Fibonacci numbers is also a proof that recursion is the problem in AutoIt (mentioned by Valik in post #24).If I can find time I will try to implement one of the L-System example to an iterative version. I bet it would be much faster...UEZThe speed of the Pythagoras() function is irrelevant when putting a timer around _GDIPlus_GraphicsDrawImage() alone is taking over 500ms. Link to comment Share on other sites More sharing options...
cppman Posted February 21, 2009 Share Posted February 21, 2009 (edited) I wrote L-System Fractals using recursion but the drawing is relatively slow when I compare it with e.g. web based implementations.Is this a limit of AutoIt or better say a limit of an interpreter language?Of course it depends also on recursions depth...Regards,UEZFirst, in your code, you need to avoid division as much as possible - it is a relatively slow operation (replace it with multiplication). Calculate any of your constants (such as $Pi / 180) before hand, and simply multiply by that. "Sqrt" is also a relatively slow function (as is Cos, Sin, etc. unless they use a lookup table) - calculate it once at the beginning, and use the result as a constant. Secondly, that "Sleep" call in your "Pythagoras" function is pointless and slows down the program by quite a bit. Thirdly, anti-aliasing is a killer operation for any program (or game). Avoid using anti-aliasing unless it is absolutely required (such as quality rendering). Also use double-buffering. Render to an off-screen surface (back-buffer), then flip the back-buffer and front-buffer. Finally, avoid using GDI for speed critical graphics applications (hence why Vista/7 uses Direct3D for rendering). Use Direct3D or OpenGL for the rendering (even if it is just the off-screen rendering), and then if you must, you can copy over the back-buffer and render it using GDI. (And then, of course, you have the inevitable speed loss from using AutoIt.) Edited February 21, 2009 by cppman Miva OS Project Link to comment Share on other sites More sharing options...
monoceres Posted February 21, 2009 Share Posted February 21, 2009 I think _WinAPI_BitBlt should be the fastest way to refresh your gui but I can't adapt any examples of its usage in AutoIt. Argh, this is the second time I fail at just that. I fucking hate device contexts expandcollapse popup#include <gdiplus.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode",1) Global Const $Width=800 Global Const $Height=600 $hWnd=GUICreate("Double buffering with GDI(+)",$Width,$Height) GUISetOnEvent(-3,"close") _GDIPlus_Startup() $hGraphics=_GDIPlus_GraphicsCreateFromHWND($hWnd) $hBitmap=_GDIPlus_BitmapCreateFromGraphics($Width,$Height,$hGraphics) $hBackbuffer=_GDIPlus_ImageGetGraphicsContext($hBitmap) $ScreenDc=_WinAPI_GetDC($hWnd) GUISetState() $i=0 $timepool=0 Do _GDIPlus_GraphicsClear($hBackbuffer,0xFF0000FF) $timer=TimerInit() ; GDI+ method ;~ _GDIPlus_GraphicsDrawImageRect($hGraphics,$hBitmap,0,0,$Width,$Height) ; GDI method $dc=_GDIPlus_GraphicsGetDC($hBackbuffer) _WinAPI_BitBlt($ScreenDc,0,0,$Width,$Height,$dc,0,0,$SRCCOPY ) _GDIPlus_GraphicsReleaseDC($hBackbuffer,$dc) If Not Mod($i,10) Then ConsoleWrite("Avarage Buffer flipping time: "&Round($timepool/10,1)&" ms."&@CRLF) $timepool=0 Else $timepool+=TimerDiff($timer) EndIf $i+=1 Until Not Sleep(100) Func close() _WinAPI_ReleaseDC($hWnd,$ScreenDc) _GDIPlus_GraphicsDispose($hBackbuffer) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndFunc After som debugging I found out that the method fails because you cannot access the bitmap from $dc, why I cannot figure out, it works when you get the dc from a graphics that was created from the screen. Argh I fucking hate device contexts Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
Valik Posted February 21, 2009 Share Posted February 21, 2009 Why are you mixing GDI+ and GDI stuff? Shouldn't you being using one or the other? I can't believe you guys are struggling with BitBlt(). There are a billion examples on the internet for using it and it should be a pretty simple conversion from the C code to AutoIt since I think all the C functions have WinAPI wrappers. Link to comment Share on other sites More sharing options...
monoceres Posted February 21, 2009 Share Posted February 21, 2009 (edited) Why are you mixing GDI+ and GDI stuff? Shouldn't you being using one or the other? I can't believe you guys are struggling with BitBlt(). There are a billion examples on the internet for using it and it should be a pretty simple conversion from the C code to AutoIt since I think all the C functions have WinAPI wrappers. Because Bitmap::DrawImage is a really slow, and weaponx suggested that bitblt would be faster, which it should since it's hardware accelerated which DrawImage is not. Well yeah, and it's not a very hard function, that's why I'm so frustrated with it. Another failed attempt: expandcollapse popup#include <gdiplus.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode",1) Global Const $Width=800 Global Const $Height=600 $hWnd=GUICreate("Double buffering with GDI(+)",$Width,$Height) GUISetOnEvent(-3,"close") _GDIPlus_Startup() $hGraphics=_GDIPlus_GraphicsCreateFromHWND($hWnd) $hBitmap=_GDIPlus_BitmapCreateFromGraphics($Width,$Height,$hGraphics) $hBackbuffer=_GDIPlus_ImageGetGraphicsContext($hBitmap) $ScreenDc=_WinAPI_GetDC($hWnd) GUISetState() Do _GDIPlus_GraphicsClear($hBackbuffer,0xFF0000FF) $gdibitmap=_GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) $dc=_WinAPI_CreateCompatibleDC($ScreenDc) _WinAPI_SelectObject($dc,$gdibitmap) _WinAPI_DeleteDC($dc) _WinAPI_DeleteObject($gdibitmap) _WinAPI_BitBlt($ScreenDc,0,0,$Width,$Height,$dc,0,0,$SRCCOPY ) Until Not Sleep(250) Func close() _WinAPI_ReleaseDC($hWnd,$ScreenDc) _GDIPlus_GraphicsDispose($hBackbuffer) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndFunc Edited February 21, 2009 by monoceres Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
Valik Posted February 21, 2009 Share Posted February 21, 2009 You're skipping stuff and trying to mix in GDI+ stuff and it's no wonder you're getting frustrated. Chances are, the HBITMAP you are trying to load into a DC is not compatible.Use the Windows API. Or use GD+. Don't mix the two unless you are 100% sure you know what you're doing. Link to comment Share on other sites More sharing options...
Malkey Posted February 22, 2009 Share Posted February 22, 2009 Well yeah, and it's not a very hard function, that's why I'm so frustrated with it.Your script works fine if you move the deleteDC to after _WinAPI_BitBlt for obvious reasons. Link to comment Share on other sites More sharing options...
monoceres Posted February 22, 2009 Share Posted February 22, 2009 Your script works fine if you move the deleteDC to after _WinAPI_BitBlt for obvious reasons.'Doh! I wonder why I put it after the cleanup, it really doesn't make any sense Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
UEZ Posted February 22, 2009 Author Share Posted February 22, 2009 (edited) First, in your code, you need to avoid division as much as possible - it is a relatively slow operation (replace it with multiplication). Calculate any of your constants (such as $Pi / 180) before hand, and simply multiply by that. "Sqrt" is also a relatively slow function (as is Cos, Sin, etc. unless they use a lookup table) - calculate it once at the beginning, and use the result as a constant. Secondly, that "Sleep" call in your "Pythagoras" function is pointless and slows down the program by quite a bit. Thirdly, anti-aliasing is a killer operation for any program (or game). Avoid using anti-aliasing unless it is absolutely required (such as quality rendering). Also use double-buffering. Render to an off-screen surface (back-buffer), then flip the back-buffer and front-buffer. Finally, avoid using GDI for speed critical graphics applications (hence why Vista/7 uses Direct3D for rendering). Use Direct3D or OpenGL for the rendering (even if it is just the off-screen rendering), and then if you must, you can copy over the back-buffer and render it using GDI. (And then, of course, you have the inevitable speed loss from using AutoIt.)Thanks for your hints - this is definitely a way to tune a code but my issue is with recursion!Neither I'm an amateur nor a pro coder just a hobbyist but I wanted to know why recursion starting at a particular level gets much (exponential?) slower. Have a look on Fibonacci numbers. Valik already answered shortly why it is slower...Currently the discussion is about double buffering methods but I like it .THANKS ANYWAY FOR YOUR POSTS!UEZ Edited February 22, 2009 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
UEZ Posted February 22, 2009 Author Share Posted February 22, 2009 (edited) Comparison of both double buffering methods: expandcollapse popup#include <gdiplus.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $hBackbuffer, $hBitmap, $hGraphics, $ScreenDc, $gdibitmap, $dc Global $hGraphic, $Bitmap, $GDI_Buffer Global $bench_start_BitBlt, $bench_start_Classic, $time_diff_bb, $time_diff_c Global Const $Width = 800 Global Const $Height = 600 Global $ticks = 2345 $hGUI = GUICreate("Double buffering with GDI(+)", $Width, $Height) ;~ GUISetOnEvent(-3, "close") GDIPlus_DB_BitBlt() Sleep(500) GDIPlus_DB_Classic() ConsoleWrite("Diff: " & Round($time_diff_c - $time_diff_bb, 4) & " ms | " & Round(Abs(100 - $time_diff_c / $time_diff_bb * 100), 2) & "%" & @CRLF & @CRLF) Exit Func GDIPlus_DB_BitBlt() _GDIPlus_Startup() $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($Width, $Height, $hGraphics) $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) $ScreenDc = _WinAPI_GetDC($hGUI) GUISetState() $bench_start_BitBlt = TimerInit() For $x = 1 To $ticks _GDIPlus_GraphicsClear($hBackbuffer, 0xFF0000FF) ;~ _GDIPlus_GraphicsFillEllipse($hBackbuffer, $Width / Random(1, 8, 1), $Height / Random(1, 8, 1), Random(1, $Width, 1), Random(1, $Height, 1)) $gdibitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) $dc = _WinAPI_CreateCompatibleDC($ScreenDc) _WinAPI_SelectObject($dc, $gdibitmap) _WinAPI_DeleteObject($gdibitmap) _WinAPI_BitBlt($ScreenDc, 0, 0, $Width, $Height, $dc, 0, 0, $SRCCOPY) _WinAPI_DeleteDC($dc) Next $time_diff_bb = TimerDiff($bench_start_BitBlt) ConsoleWrite("BitBlt Runtime: " & Round($time_diff_bb, 2) & " ms. Average: " & Round($time_diff_bb / $ticks, 4) & " ms." & @CRLF) close() EndFunc Func GDIPlus_DB_Classic() _GDIPlus_Startup () $hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI) $Bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic) $GDI_Buffer = _GDIPlus_ImageGetGraphicsContext($Bitmap) GUISetState() $bench_start_Classic = TimerInit() For $x = 1 To $ticks _GDIPlus_GraphicsClear($GDI_Buffer, 0xFF0000FF) ;~ _GDIPlus_GraphicsFillEllipse($GDI_Buffer, $Width / Random(1, 8, 1), $Height / Random(1, 8, 1), Random(1, $Width, 1), Random(1, $Height, 1)) _GDIPlus_GraphicsDrawImageRect($hGraphic, $Bitmap, 0, 0, $width, $height) Next $time_diff_c = TimerDiff($bench_start_Classic) ConsoleWrite("Classic Runtime: " & Round($time_diff_c, 2) & " ms. Average: " & Round($time_diff_c / $ticks, 4) & " ms." & @CRLF & @CRLF) close2() EndFunc Func Close2() _GDIPlus_BitmapDispose($Bitmap) _GDIPlus_GraphicsDispose($GDI_Buffer) _GDIPlus_GraphicsDispose ($hGraphic) _GDIPlus_Shutdown () EndFunc Func close() _WinAPI_ReleaseDC($hGUI, $ScreenDc) _GDIPlus_GraphicsDispose($hBackbuffer) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() EndFunc ;==>close My results on Dell Latitude D830 (Vista x32): BitBlt Runtime: 18269.56 ms. Average: 7.7909 ms. Classic Runtime: 20401.94 ms. Average: 8.7002 ms. Diff: 2132.3756 ms | 11.67% Seems to be approx. 10% faster! UEZ Edited February 22, 2009 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Wus Posted February 24, 2009 Share Posted February 24, 2009 Another point to note is that recursion is generally an operation that sacrifices speed in the name of clarity and simplicity. Frequently if efficiency is the concern then you turn the recursion into iteration. This is the heart of the idea of dynamic programming. From the code I see, this isn't terribly relevant, but topic's name begged me to mention this. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now