Jump to content

EndIf "overhead"


Go to solution Solved by AspirinJunkie,

Recommended Posts

Posted

I was reading some docs recently for If...Then and noticed one of the paragraphs:

Quote

This version of the If statement is used to execute a single statement without the overhead of an EndIf.

I've added bold to the part that I have a concern about. According to the docs, that tells me that a single line If statement performs better in comparison to and If statement that ends with EndIf.

That made me start to think about converting all of my If...EndIf statements to single line If statements.

However, since I have been performance testing everything that goes into my current project, I realized pretty quickly that the docs were wrong about the EndIf "overhead".

So I decided to search the forums here since these forums are a gold mine of information. I came across a great post (with script) by the great @guinness for comparing the performance. I have updated the script a bit:

Global $iTimer, $iVariable = 1

$iTimer1 = TimerInit()
For $A = 1 To 10000
    If $iVariable Then $iVariable = 1
Next
$iTimer1 = Round(TimerDiff($iTimer1), 1)
ConsoleWrite("10,000 runs (single line If statement): " & @TAB & $iTimer1 & "ms" & @CRLF)

$iTimer2 = TimerInit()
For $A = 1 To 10000
    If $iVariable Then
        $iVariable = 1
    EndIf
Next
$iTimer2 = Round(TimerDiff($iTimer2), 1)
ConsoleWrite("10,000 runs (If statement with EndIf): " & @TAB & @TAB & $iTimer2 & "ms" & @CRLF & @CRLF)

$iDifference = Round(($iTimer1 - $iTimer2) / $iTimer2, 2)
ConsoleWrite("Percentage Difference: " & @TAB & @TAB & @TAB & @TAB & @TAB & @TAB & $iDifference * 100 & "%" & @CRLF)

The difference is really quite interesting.

But as I mentioned, the problem that I have is with the wording "without the overhead of an EndIf" in the documentation. If it wasn't for me doing performance testing comparisons recently, I probably would have went ahead and changed dozens of If...EndIf statements in my current project to single line If statements and these get called sometimes dozens of times per second.

As always, thank you for your time. :)

Posted
Global $iTimer, $iVariable = 1

For $tryNo = 1 To 3
    Sleep(1000)
    $iTimer1 = TimerInit()
    For $A = 1 To 10000
        If $iVariable Then $iVariable = 1
    Next
    $iTimer1 = Round(TimerDiff($iTimer1), 1)
    ConsoleWrite("10,000 runs (single line If statement): " & @TAB & $iTimer1 & "ms" & @CRLF)

    $iTimer2 = TimerInit()
    For $A = 1 To 10000
        If $iVariable Then
            $iVariable = 1
        EndIf
    Next
    $iTimer2 = Round(TimerDiff($iTimer2), 1)
    ConsoleWrite("10,000 runs (If statement with EndIf): " & @TAB & @TAB & $iTimer2 & "ms" & @CRLF)

    $iDifference = Round(($iTimer1 - $iTimer2) / $iTimer2, 2)
    ConsoleWrite("Percentage Difference: " & @TAB & @TAB & @TAB & @TAB & @TAB & @TAB & $iDifference * 100 & "%" & @CRLF & @CRLF)
Next
Exit
10,000 runs (single line If statement):     40.5ms
10,000 runs (If statement with EndIf):      3.1ms
Percentage Difference:                      1206%

10,000 runs (single line If statement):     5.7ms
10,000 runs (If statement with EndIf):      3ms
Percentage Difference:                      90%

10,000 runs (single line If statement):     5.8ms
10,000 runs (If statement with EndIf):      3ms
Percentage Difference:                      93%

I'll write what makes the code more readable. Anyone having to depend on this, needs to rethink their code.  My 2 cents

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted

I am also opinionated about single line statements. They decrease the readability often more than just a bit.

My recommendation for your specific case:
Try to optimise the algorithms, function logic instead of if-condition optimisation. I strongly believe there is more potential to optimize 😀 .

Best regards
Sven

==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet

Spoiler

🌍 Au3Forums

🎲 AutoIt (en) Cheat Sheet

📊 AutoIt limits/defaults

💎 Code Katas: [...] (comming soon)

🎭 Collection of GitHub users with AutoIt projects

🐞 False-Positives

🔮 Me on GitHub

💬 Opinion about new forum sub category

📑 UDF wiki list

✂ VSCode-AutoItSnippets

📑 WebDriver FAQs

👨‍🏫 WebDriver Tutorial (coming soon)

Posted
1 hour ago, SOLVE-SMART said:

Try to optimise the algorithms, function logic instead of if-condition optimisation. I strongly believe there is more potential to optimize

Thanks Sven. I agree with you 100%. Every time I look it over, I always find things that can be optimized or improved in various ways. I seem to actually enjoy this aspect of learning better ways to do things.

Normally I don’t worry too much about performance. But in this case it’s for a WinEventHook so it has to be able to handle everything that goes through the hook.

Posted
5 hours ago, SOLVE-SMART said:

Try to optimise the algorithms, function logic instead of if-condition optimisation. I strongly believe there is more potential to optimize 😀 .

Big Agree

I mean, it definitely helps if you're fighting a race condition but it's not a good idea to get yourself in one in the first place. 👀

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11, MSEdgeRedirect
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Posted
6 hours ago, AspirinJunkie said:

So it depends on whether the condition is met or not. If it is met, then the classic If-EndIf is faster. If it is not met, the one-liner is faster.
When conditions are balanced, their times will be roughly the same.

Thank you so much. That was very enlightening, both the script and the way that you worded everything. I had not even put any thought into whether the performance would differ depending on whether or not the condition was met.

And then, as you mentioned, these are really nanoseconds that were are talking about here and therefore likely not even worth my time trying to optimize in this area. As others have mentioned, I should ensure that the code in this area is readable first and foremost.

16 hours ago, SOLVE-SMART said:

Try to optimise the algorithms, function logic instead of if-condition optimisation.

You were right about not focusing on optimizing if-conditions and that I should be focusing optimization elsewhere. :)

For what it's worth, despite AutoIt not being built for or intended for performance, I am really happy with the performance that I get out of my _WinEventProc function (SetWinEventHook). It's a busy function but AutoIt handles it well and I had already put a lot of optimization work into it over the past few months among other changes to make it as efficient as possible.

Some of you might already be aware that I had already made significant performance improvements recently, thanks for the Fastest method to get process name from handle thread which got me making custom versions of all of the _WinAPI_* functions that I already use. There were some real, legitimate differences in performance that came out of that thread.

Perhaps me nitpicking about If...Then statement performance is just being greedy and trying to pull in more performance in an area that is less relevant but also likely that I just need to focus my mind elsewhere and stop looking for performance improvements, when in reality, I am more than satisfied with the overall performance. 😄

Posted (edited)
8 hours ago, AspirinJunkie said:

produces for me:

name             time
--------------------------------------
       If-EndIf True:     0.000260 ms
      If-EndIf False:     0.000161 ms
    If-OneLiner True:     0.000481 ms
   If-OneLiner False:     0.000088 ms

I decided to investigate by inverting the conditions via NOT (and inverting variable values and assignments) with the following results. If-OneLiner False becomes the slowest of the bunch. Edit: Fixed variables. Got similar results as previous. 

name             time
--------------------------------------
    IfNot-EndIf True:     0.000334 ms
   IfNot-EndIf False:     0.000226 ms
 IfNot-OneLiner True:     0.000539 ms
IfNot-OneLiner False:     0.000156 ms



 

Edited by rcmaehl
Fix Bad Code

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11, MSEdgeRedirect
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Posted

They made me doubt for a moment, I think this condition is one of the few admitted, generally it has to be enclosed in other languages {...}

myLogin 🛡️

Posted (edited)

I'm sure there's some CPU Branch Predictor Optimizations that can be done. However, as you've seen in your Process Name from Handle thread, there's a LOT more performance that can be gained by reusing resources, cutting out unneeded code, and other optimizations.
 

Also, don't be afraid to do things out of order. You may be surprised what still works ;) 

$iSIHost = ProcessExists("sihost.exe")

While True
   $aProcessList = _WinAPI_EnumChildProcess($iSIHost)
   If @error Then ContinueLoop
   ProcessClose($aProcessList[1][0])
   $sCommandline = _WinAPI_GetProcessCommandLine($aProcessList[1][0])
   $sProcessPath = _WinAPI_GetProcessFileName($aProcessList[1][0])
WEnd

 

And you can always fix a mistake if you're overzealous ;) 

$iSIHost = ProcessExists("sihost.exe")

While True
   $aProcessList = _WinAPI_EnumChildProcess($iSIHost)
   If @error Then ContinueLoop
   ProcessClose($aProcessList[1][0])
   $sCommandline = _WinAPI_GetProcessCommandLine($aProcessList[1][0])
   $sProcessPath = _WinAPI_GetProcessFileName($aProcessList[1][0])
   If Not $aProcessList[1][1] = "msedge.exe" Then ShellExecute($sProcessPath, $sCommandLine)
WEnd

 

Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11, MSEdgeRedirect
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Posted
2 hours ago, WildByDesign said:

Perhaps me nitpicking about....

..perhaps.. . Perhaps is good. Not because one of your questions did not bring the house down, or you were right or not about making a big deal out of, something. Is good, is all good.
So keep asking if there is a question. I enjoy the threads even if I don't have either time, or anything to contribute to it.
This if-then-else thing, ...I had no idea, nor ever came up in my brain.

Thinking about it, at times I use Switch as an If when is practical ( I don't care much about speed or memory with today's hardware )

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Posted
3 hours ago, argumentum said:

So keep asking if there is a question. I enjoy the threads even if I don't have either time, or anything to contribute to it.

I appreciate it. Thank you. I figure that it never hurts to ask questions and sometimes asking questions and having dialogue with like-minded people.

3 hours ago, argumentum said:

Thinking about it, at times I use Switch as an If when is practical

That actually reminds me that I was planning to look into that at some point in time. I don't have very much experience with Switch so far. I should see if I can convert some of my script over to Switch because it's nice and tidy looking.

Posted
3 hours ago, rcmaehl said:

Also, don't be afraid to do things out of order. You may be surprised what still works

Thank you. That is great information. I've only been learning AutoIt for a little over a year now but I really do need to start thinking outside the box a bit more and get a bit more creative. AutoIt definitely provides the flexibility for that creativity.

Posted (edited)

It's good to have a constant desire to write good and fast running code but on this matter I have the same feeling as @argumentum and as long as I use AutoIt I don't care too much so I use a mix of different conditional statements that make sense in each situation. If the performance it's such an issue to make me fight for each 1000th part of a ms probably I want to code in another language. But again as a good practice and for learning purpose your question is legit.

Edited by Andreik
Posted
52 minutes ago, Andreik said:

If the performance it's such an issue to make me fight for each 1000th part of a ms probably I want to code in another language

I agree, that does make the most sense.

I think the problem here is that I became too obsessed/interested with gaining more performance savings when it really was not needed.

But on the positive side, I have learned so much more from this performance adventure and did end up making things much more efficient with some aspects of it.

And I absolutely must say, the AutoIt community here is the best. I love it how many people come together with different ideas from various perspectives. :)

Posted

Hi everyone,

Thanks for this super interesting thread! I really appreciate the educational aspect of this topic and the way you've shared your insights. Your in-depth investigations into performance are inspiring, and it's impressive to see how much you've dug into the subject as a team! 😊

Just a small remark: while reading your discussions on optimization, I was surprised not to see any mention of the ternary operator. It seems to me that in some cases, it could be an elegant and concise alternative to simplify If...EndIf statements, while also offering a slight performance boost. Have you explored this approach collectively, or perhaps it wasn't applicable to this specific case? 

From 0 and 1 to the stars, it all starts with binary, Numeric1
 
Posted
28 minutes ago, Numeric1 said:

Just a small remark: while reading your discussions on optimization, I was surprised not to see any mention of the ternary operator. It seems to me that in some cases, it could be an elegant and concise alternative to simplify If...EndIf statements, while also offering a slight performance boost. Have you explored this approach collectively, or perhaps it wasn't applicable to this specific case? 

Thank you for your response. I appreciate that you've taken time to share some insight and suggestions as well.

I personally have never used Ternary before. I'm still quite new to AutoIt and have a lot to learn. So to be perfectly honest, I don't really have a good understanding of how or when to use Ternary over the other options.

This thread (and possibly another thread or two) was really about trying to get the most performance out of, or better efficiency, of the _WinEventProc (SetWinEventHook) function of my Immersive UX project. Since all running processes on the system filter through it, finding various ways to make it more efficient has been incredibly helpful. With the help of this community, it has been really beneficial.

If you are curious if Ternary can fit in anywhere and if you have a few minutes, you can have a peak at the hook function (https://github.com/WildByDesign/ImmersiveUX/blob/main/ImmersiveEngine.au3#L587). It's got a lot of things that help make it more efficient, but I am always open to more. And most importantly, I am always interested in learning more.

Posted (edited)
1 hour ago, WildByDesign said:

Thank you for your response. I appreciate that you've taken time to share some insight and suggestions as well.

I personally have never used Ternary before. I'm still quite new to AutoIt and have a lot to learn. So to be perfectly honest, I don't really have a good understanding of how or when to use Ternary over the other options.

This thread (and possibly another thread or two) was really about trying to get the most performance out of, or better efficiency, of the _WinEventProc (SetWinEventHook) function of my Immersive UX project. Since all running processes on the system filter through it, finding various ways to make it more efficient has been incredibly helpful. With the help of this community, it has been really beneficial.

If you are curious if Ternary can fit in anywhere and if you have a few minutes, you can have a peak at the hook function (https://github.com/WildByDesign/ImmersiveUX/blob/main/ImmersiveEngine.au3#L587). It's got a lot of things that help make it more efficient, but I am always open to more. And most importantly, I am always interested in learning more.

 

Quote

False Positives seem to be a "cat & mouse game" 

Try adding -mx=0 in your CI for 7z

Edited by rcmaehl
fix flag

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11, MSEdgeRedirect
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Posted
17 minutes ago, rcmaehl said:

Try adding -mx=0 in your CI for 7z

That's a good suggestion. I will give it a try. Defender doesn't detect the actual compiled binaries, just the archive that contains the binaries. I hadn't thought about changing the compression like that but it definitely makes sense. Thanks.

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
  • Recently Browsing   0 members

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