Sign in to follow this  
Followers 0
Xibalba

Performance optimization - syntax answers and restructuring ideas welcome

15 posts in this topic

My program is very dependent on running fast. I currently have this code running about 8 times each second (at the end of an endless loop until exiting):

If NOT (StringLen($System_Log) == 0)
  PrintLogToTxt()
  $System_Log = ""
EndIf

Note: $System_Log is a global string containing between 0 to 150,000 characters each loop (varies).

This should be faster than using

If NOT ($System_Log == "")

or

If $System_Log <> ""

..but I would like confirmation on this and/or tips on further optimization.

I'm thinking about running the first mentioned code every 2, or 4 loops instead of every. Would this speed up things? (the $System_Log string would be 4x larger)

Question 2)

I also have gazillions of Case, Switch, and If-Else statements. After some research into this - "If" is obviously the slowest. But which is the fastest in general - case or switch?

Thanks in advance

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

If $System_Log then
  PrintLogToTxt()
  $System_Log = ""
EndIf

$b = "1"
For $i = 2 To 150000
    $b &= "1"
Next

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    if $b Then $y +=1
Next
ConsoleWrite(TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    if NOT (StringLen($b) == 0) Then $y +=1
Next
ConsoleWrite(TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    If NOT ($b == "")  Then $y +=1
Next
ConsoleWrite(TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    if $b <> ""  Then $y +=1
Next
ConsoleWrite(TimerDiff($timer) & @tab & $y & @CRLF)

$a = 1
$b = 2

$timer = TimerInit()
For $i = 0 To 1000000
    If $a = $b Then
    Else
    EndIf
Next
ConsoleWrite(TimerDiff($timer) & @CRLF)

$timer = TimerInit()
For $i = 0 To 1000000
    Select
        Case $a = $b
        Case Else
    EndSelect
Next
ConsoleWrite(TimerDiff($timer) & @CRLF)

$timer = TimerInit()
For $i = 0 To 1000000
    Switch $a
        Case $b
        Case Else
    EndSwitch
Next
ConsoleWrite(TimerDiff($timer) & @CRLF)
Edited by KaFu

Share this post


Link to post
Share on other sites

Thanks for some input.

(New) Question 3)

If I have a lot of boolean variables which i check and/or set, which is faster:

If $myBool Then
  $myBool = False
EndIf

or just simply set it every time (at this specific line):

$myBool = False

This code runs a few hundred times per second, so it will matter in the long run.

Thanks in advance

Share this post


Link to post
Share on other sites

I've thought about optimization in the past with AutoIt, and basically came to the conclusion that the less text AutoIt has to parse, the better.

The fastest - set $myBool to 0 each time. 'False' isn't really needed other than for text output. A setting of any value other than 0 can be interpreted as 'True'.

Share this post


Link to post
Share on other sites

I think the same might be said for the size of the AU3 file (or I could be wrong) If I have a single If...EndIf statement, I tend to have it on the one line.

If $iInt = 0 Then ConsoleWrite("0" & @CRLF)

Instead of...

If $iInt = 0 Then 
   ConsoleWrite("0" & @CRLF)
EndIf

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

I've thought about optimization in the past with AutoIt, and basically came to the conclusion that the less text AutoIt has to parse, the better.

I've always found multiline If's to be faster than single line If's though. Doesn't stop me from using single line If's.

To answer Q3: From what I can test it seems that evaluating this:

If False Then
    ;this never gets executed
    $myBool = False
EndIf

Takes about twice as long as setting this, when $myBool is always false:

$myBool = False

In fact this:

$myBool = False
$myBool = True

Is only marginally slower than evaluating the if statement above, even if the if statement never has to actually change any variables.

So in no circumstance could it be faster to use the if statement. This changes when you are setting a lot of variables, or more complex variables, but for a bool, just set it every time.

One interesting thing I read on the topic a while ago is that autoit takes longer to execute code with longer variable and function names. So you might want to replace it all for names with 1 to 3 characters depending on how many names you need. I think there might be an obfuscator option to do so.

The ultimate performance optimization would probably to learn something besides AutoIt for these applications. (that's not going to make me popular now is it?)

Share this post


Link to post
Share on other sites

I think there might be an obfuscator option to do so.

This is my standard option to boost performance :)...

#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0

Share this post


Link to post
Share on other sites

@Xibalba You might also like Bowmore's AU3Profiler, search the Examples forum

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

I've always found multi line IFs to be faster than single line IFs though. Doesn't stop me from using single line IFs.

I'm of the opinion that the first priority should be that the code should be clear and the logic used easy to follow. Only when that has been achieved and the application is working as expected should we worry about speed and then concentrate on those areas which are the real bottle necks.

Tvern I was interested in your comment regarding the speed of multi line IFs verses single line IFs, so I did a bit of testing. It appears that there is a significant difference in speed between the two forms. Strangely though the difference is reversed depending on whether the test expression evaluates true or false as shown in the tests below.

In the tests labeled AT BT CT DT the expression evaluates to true.

In the tests labeled AF BF CF DF the expression evaluates to false.

$b = "qwertyuiytrew"  ;evaluates to true

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    if $b <> "" Then $y +=1
Next
ConsoleWrite("AT " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i=1 To 1000000
If $b<>"" Then
$y+=1
EndIf
Next
ConsoleWrite("BT " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
if $b Then $y+=1
Next
ConsoleWrite("CT " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
if $b Then
$y+=1
EndIf
Next
ConsoleWrite("DT " & TimerDiff($timer) & @tab & $y & @CRLF)


$b=""  ;evaluates to false
$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
    if $b <> "" Then $y +=1
Next
ConsoleWrite("AF " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i=1 To 1000000
If $b<>"" Then
$y+=1
EndIf
Next
ConsoleWrite("BF " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
if $b Then $y+=1
Next
ConsoleWrite("CF " & TimerDiff($timer) & @tab & $y & @CRLF)

$y = 0
$timer = TimerInit()
For $i = 1 To 1000000
if $b Then
$y+=1
EndIf
Next
ConsoleWrite("DF " & TimerDiff($timer) & @tab & $y & @CRLF)

Edit: Spelling

Edited by Bowmore

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Tvern & Bowmore, that's interesting regarding the multi--line If/EndIf's.

I've tested Bowmore's code, removing all unneeded spaces and adding a sleep before execution of the main script (sometimes AutoIt needs 'initialization' time with a script), and this is the result:

AT 2680.35570615504 1000000
BT 1900.54062567844 1000000
CT 1917.61630901653 1000000
DT 1120.32454568287 1000000
AF 1306.79400458893 0
BF 1542.82777028091 0
CF 547.604857968695 0
DF 803.950824347737 0

So on my PC, ~800 milliseconds extra for a matched single-line 'If..Then'. And ~250 ms. extra for non-matching multiline 'If..Then.EndIf' statements.

Very interesting.

I guess the scripter could determine which case is most likely to happen and then tweak the code based on that. Or just stick with 'If..Then..Endif', as that has the least performance impact either way.

*edit: Thinking on this.. most of my code within loops where there is a single-line 'If..Then' usually results in an ExitLoop or Return, so those are best left alone..

Hmm.. and most people don't have anything running 1000000 times, so the scores above need to be taken with that in mind.

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

Hmm.. and most people don't have anything running 1000000 times, so the scores above need to be taken with that in mind.

Yeah I doubt this will have much practical use in most applications, but it's nice to have an idea of how these things behave. I was pretty surprised with the results I gor from Bowmore's script myself.

Share this post


Link to post
Share on other sites

@Ascend4nt

I agree it is easy to get carried away with small performance differences that don't have much impact in the real world. However personally I frequently use AutoIt at work to manipulate files with 25 to 50 million lines so small differences can somtimes make a significant time the application takes to run. Compared to using AutoIt in the first place is the biggest productivity boost. For many jobs, even if it is a one off the time taken to write a script and run it is far quicker than the alternative especially when you have a number of preprepared template scripts for different types of similar jobs.

If you know something about the data you are processing significant performance increases can be achieved by ensuring the the most frequently occurring scenarios are checked for first in IF...Then; Switch or Select blocks.


"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

whatever Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
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
Sign in to follow this  
Followers 0