Jump to content

DllClose() is still a good idea? - (Moved)


Recommended Posts

  • Developers

Moved to the appropriate AutoIt General Help and Support forum, as the Developer General Discussion forum very clearly states:

Quote

General development and scripting discussions.


Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums.

Moderation Team

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

To be honest, DllOpen is as useless as DllClose.  Do you own testing, with and without DllOpen.  You are saving nanoseconds only on each call.  It will not make your slow program suddenly fast. ;) 

Link to comment
Share on other sites

Maybe not really needed anymore on Windows 10/11 and/or current version of AutoIt. I see it there as a "good practice" for managing your resources if you ever write in other languages where it matters more. So it's not "useless and superfluous", and it might be useful for people still using older versions of Windows that maybe don't handle it as well.

As Nine said, you're saving microseconds, but there is a small gain in opening the DLL yourself, around 9-10%. Unless you're making literally millions of calls though, it's not going to make much of a difference. Here's a test I did for 1,000,000 runs with kernel32 calling GetTickCount64:

+———————————————+—————————————————+———————————————+——————————————+—————————————+
 | Function Name | Time Taken (ms) | Avg Time (ms) | Std Dev (ms) | Faster By % |
 +———————————————+—————————————————+———————————————+——————————————+—————————————+
 | DllCall       |         8179.74 |        0.0082 |       0.0056 |        0.00 |
+| DllCall(Open) |         7444.30 |        0.0074 |       0.0032 |        8.99 |
 +———————————————+—————————————————+———————————————+——————————————+—————————————+
 |  Total time   |        15624.03 |               |              |             |
 +———————————————+—————————————————+———————————————+——————————————+—————————————+

So, is it worth doing? Yeah, why not? Is it necessary if you open a DLL to close it? Nah, AutoIt and/or Windows will manage that pretty well for you. Is not doing it hurting you? Nah.

Edited by mistersquirrle

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

Using DllCallAddress() is even faster, but as the team said, it's only worth to optimize when you've got a lot of calls, normally the bottlenecks are somewhere else.

I analyzed how many calls are made in SMF and switched to DllCallAddress() for some calls of which literally million of calls where made in huge and complex searches. Overall gain I would say is max 5 to 10% in speed, now the hardware itself seems to be the bottleneck and slowest part in searching for files.

 

#include <WinAPISys.au3>

$iTimer = TimerInit()
For $i = 1 To 1000000
    _WinAPI_GetTickCount64()
Next
ConsoleWrite(_WinAPI_GetTickCount64() & @CRLF)
ConsoleWrite(TimerDiff($iTimer) & @CRLF & @CRLF)

$iTimer = TimerInit()
For $i = 1 To 1000000
    DllCall('kernel32.dll', 'uint64', 'GetTickCount64')
Next
ConsoleWrite(DllCall('kernel32.dll', 'uint64', 'GetTickCount64')[0] & @CRLF)
ConsoleWrite(TimerDiff($iTimer) & @CRLF & @CRLF)

$iTimer = TimerInit()
$dll = DllOpen("kernel32.dll")
For $i = 1 To 1000000
    DllCall($dll, 'uint64', 'GetTickCount64')
Next
ConsoleWrite(DllCall($dll, 'uint64', 'GetTickCount64')[0] & @CRLF)
DllClose($dll)
ConsoleWrite(TimerDiff($iTimer) & @CRLF & @CRLF)

$iTimer = TimerInit()
Global $hInstance_Kernel32_dll = _WinAPI_GetModuleHandle("kernel32.dll")
Global $hAddress_Kernel32_dll_GetTickCount64 = _WinAPI_GetProcAddress($hInstance_Kernel32_dll, "GetTickCount64")
For $i = 1 To 1000000
    DllCallAddress('uint64', $hAddress_Kernel32_dll_GetTickCount64)
Next
ConsoleWrite(DllCallAddress('uint64', $hAddress_Kernel32_dll_GetTickCount64)[0] & @CRLF)
ConsoleWrite(TimerDiff($iTimer) & @CRLF & @CRLF)

 

Edited by KaFu
Link to comment
Share on other sites

  • Developers
15 hours ago, Nine said:

To be honest, DllOpen is as useless as DllClose.  Do you own testing, with and without DllOpen.  You are saving nanoseconds only on each call.  It will not make your slow program suddenly fast. ;) 

Probably but not the best of advice to give when one is doing many DLLCalls to a specific DLL Function.
This is similar as the FileOpen()/FileClose() and FileWrite(). DOing to occasional FileWrite() I would agree there's not too much benefit doing a FileOpen & Close, but when writing a lot of separate lines to a file I would always Do a FileOpen() and use it's handle in the FileWrite(). Just a good practice to do so. ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Yep, I agree with you @Jos on the file I/O.  But, remember that tons of functions we are currently using (implying DllCall, e.g. WinAPI) do not do DllOpen.  Do we feel the difference ?

Link to comment
Share on other sites

  • Developers
2 hours ago, Nine said:

Do we feel the difference ?

Yep ... and still the advices isn't per se the right one. ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

This works just fine... for while. For me the speed of the script stalls at around ~330k open dlls, and it seems to accumulate some 32kb or so per open dll.

So if you only open a few dlls, I guess it doesn't matter. If you script runs in loops and opens 100k+ dlls, I guess it will stall at some point.

#include <GUIConstantsEx.au3>

for $i = 1 to 1000000
    DllOpen("user32.dll")
    if Mod($i,1000) = 0 then ConsoleWrite($i & @crlf)
Next

Local $hGUI = GUICreate("Example")
GUISetState(@SW_SHOW, $hGUI)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

 

Edited by KaFu
Link to comment
Share on other sites

  • 2 weeks later...
On 3/30/2023 at 6:42 AM, mistersquirrle said:
+———————————————+—————————————————+———————————————+——————————————+—————————————+
| Function Name | Time Taken (ms) | Avg Time (ms) | Std Dev (ms) | Faster By % |
+———————————————+—————————————————+———————————————+——————————————+—————————————+
| DllCall       |         8179.74 |        0.0082 |       0.0056 |        0.00 |
| DllCall(Open) |         7444.30 |        0.0074 |       0.0032 |        8.99 |
+———————————————+—————————————————+———————————————+——————————————+—————————————+
|  Total time   |        15624.03 |               |              |             |
+———————————————+—————————————————+———————————————+——————————————+—————————————+

Hey, not bumping this but wanted to point something ^^

For people familiar with parametric testing, i could bet there's no significative difference of means ...

Long story short => the avg time for a call might not be different depending on the method (for a statistician pov) (a cue : std dev shas same magnitude than means O.O)

 

NOTE: there's lot of stuff going on about 'opening' dll etc. You want to load the library in the adress space, reference and import the exported symbols, looking for one specific etc. But, for your information, kernel32, user32, crt, and many more are already loaded by the autoit interpreter (suprised ?? xD). If you really want to 'optimize' your code when calling those libs, you should know: they are *ALWAYS* loaded on the same range (and i'm not talking about autoit here), so you could just fetch one time the adress of w/e you want and then use a dllcalladress ... but for some, not so stupid, reasons : this is overkill and not that smart to do so (also makes your code quite unreadable) for the sake of some microseconds optimisation.

Edited by 636C65616E
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...