Professor_Bernd Posted November 10, 2020 Author Share Posted November 10, 2020 6 hours ago, water said: You will notice a difference if you call a function many times in aloop. Since this is the case here, your idea is a good idea. Thanks a lot! Link to comment Share on other sites More sharing options...
JockoDundee Posted November 10, 2020 Share Posted November 10, 2020 The three candidates for timing are (so far): The StringRepeat: Func StringRepeatTest($sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), _StringRepeat(" ", $iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc The StringLeft: Func StringLeftTest($sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), StringLeft(" ",$iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc The StringArray: Func StringArrayTest($sString, $iTabLen = 8) Local $sSpaces[9]=[""," "," "," "," "," "," "," "," "] Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), $sSpaces[$iSpaceLeft + 1], 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc Any others? Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
JockoDundee Posted November 10, 2020 Share Posted November 10, 2020 Preliminary Results based on a short test string: START ----- StringRepeatTest------ TIMING FOR 1000: 0.303 TIMING PER ITER: 0.000303 END --- StringRepeatTest--- START ----- StringLeftTest------ TIMING FOR 1000: 0.144 TIMING PER ITER: 0.000144 END --- StringLeftTest--- START ----- StringArrayTest------ TIMING FOR 1000: 0.137 TIMING PER ITER: 0.000137 END --- StringArrayTest--- Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
JockoDundee Posted November 10, 2020 Share Posted November 10, 2020 Here’s the actual test rig i used if someone wants to validate it: expandcollapse popup#include <String.au3> $str="1234567 123456 12345 1234 123 12 1 " $str&="1234567 123456 12345 1234 123 12 1 " $str&="1234567 123456 12345 1234 123 12 1 " $m=1000 TimeIt("StringRepeatTest") TimeIt("StringLeftTest") TimeIt("StringArrayTest") Func TimeIt($version) ConsoleWrite ("START ----- "& $version & "------" & @CRLF & @CRLF) Switch $version Case "StringRepeatTest" $t1=ms() For $n=1 To $m StringRepeatTest($str) Next $t2=ms() Case "StringLeftTest" $t1=ms() For $n=1 To $m StringLeftTest($str) Next $t2=ms() Case "StringArrayTest" $t1=ms() For $n=1 To $m StringArrayTest($str) Next $t2=ms() EndSwitch $t3=Round($t2-$t1,6) $t4=Round($t3/$m, 6) ConsoleWrite("TIMING FOR "& $m &": "& $t3 & @CRLF) ConsoleWrite("TIMING PER ITER: "& $t4 & @CRLF & @CRLF) ConsoleWrite ("END --- "& $version &"---" & @CRLF & @CRLF & @CRLF) EndFunc Func ms() Return (@HOUR*3600)+(@MIN*60)+(@SEC*1)+(@MSEC/1000) EndFunc Func StringRepeatTest($sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), _StringRepeat(" ", $iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc Func StringLeftTest($sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), StringLeft(" ",$iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc Func StringArrayTest($sString, $iTabLen = 8) Local $sSpaces[9]=[""," "," "," "," "," "," "," "," "] Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, Chr(9), $sSpaces[$iSpaceLeft + 1], 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Zedna Posted November 10, 2020 Share Posted November 10, 2020 (edited) Another optimisation tip: Avoid calling Chr(9) inside loop, instead call it only once before loop $tab=Chr(9) or $tab=@TAB and inside loop use only variable $tab Edited November 10, 2020 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
Nine Posted November 11, 2020 Share Posted November 11, 2020 Went from 497ms to 317ms implementing both @Zedna (~60ms) and @water (~120ms) suggestions with the same file. Close to 25% faster. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
water Posted November 11, 2020 Share Posted November 11, 2020 My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
JockoDundee Posted November 11, 2020 Share Posted November 11, 2020 1 hour ago, Nine said: Went from 497ms to 317ms implementing both @Zedna (~60ms) and @water (~120ms) suggestions with the same file. Close to 25% faster. Nine, can you share your test file? Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Nine Posted November 11, 2020 Share Posted November 11, 2020 #include <String.au3> #include <File.au3> Local $hTimer = TimerInit() Local $aFileLines _FileReadToArray("Temp\AutoIt3Wrapper.au3",$aFileLines) if @error Then Exit MsgBox ($MB_SYSTEMMODAL,"",@error) For $i = 1 to $aFileLines[0] $aFileLines[$i] = _TabsToSpaces($aFileLines[$i]) Next _FileWriteFromArray("Temp\AutoIt3Wrapper New.au3",$aFileLines,1) MsgBox ($MB_SYSTEMMODAL,"",TimerDiff($hTimer)) Func _TabsToSpaces($sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, @TAB, StringLeft(" ",$iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd Return $sString EndFunc ;==>_TabsToSpaces Just copy AutoIt3Wrapper.au3 file to local test folder “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
JockoDundee Posted November 11, 2020 Share Posted November 11, 2020 50 minutes ago, Nine said: Just copy AutoIt3Wrapper.au3 file to local test folder Slight change (ByRef) shaves a millisecond or two - less than I expected, but something... #include <String.au3> #include <File.au3> Local $hTimer = TimerInit() Local $aFileLines _FileReadToArray("Temp\AutoIt3Wrapper.au3",$aFileLines) if @error Then Exit MsgBox ($MB_SYSTEMMODAL,"",@error) For $i = 1 to $aFileLines[0] _TabsToSpaces($aFileLines[$i]) Next _FileWriteFromArray("Temp\AutoIt3Wrapper New.au3",$aFileLines,1) MsgBox ($MB_SYSTEMMODAL,"",TimerDiff($hTimer)) Func _TabsToSpaces(ByRef $sString, $iTabLen = 8) Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, @TAB, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, @TAB, StringLeft(" ",$iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, @TAB, 1) WEnd EndFunc ;==>_TabsToSpaces Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Professor_Bernd Posted November 12, 2020 Author Share Posted November 12, 2020 12 hours ago, Nine said: Went from 497ms to 317ms implementing both @Zedna (~60ms) and @water (~120ms) suggestions with the same file. Close to 25% faster. It only takes the blink of an eye for almost 6,000 lines. Link to comment Share on other sites More sharing options...
Zedna Posted November 12, 2020 Share Posted November 12, 2020 On 11/10/2020 at 11:39 PM, Zedna said: Another optimisation tip: Avoid calling Chr(9) inside loop, instead call it only once before loop $tab=Chr(9) or $tab=@TAB and inside loop use only variable $tab As I said: inside of loop use $tab (not @TAB) $start = TimerInit() For $i = 1 To 100000 $s = "1" & Chr(9) Next ConsoleWrite("Chr(9): " & TimerDiff($start) & @CRLF) $start = TimerInit() For $i = 1 To 100000 $s = "1" & @TAB Next ConsoleWrite("@TAB: " & TimerDiff($start) & @CRLF) $start = TimerInit() $tab = @TAB For $i = 1 To 100000 $s = "1" & $tab Next ConsoleWrite("$tab: " & TimerDiff($start) & @CRLF) #cs Chr(9): 126.61379197976 @TAB: 154.890994068918 $tab: 93.2801592911952 #ce Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
JockoDundee Posted November 12, 2020 Share Posted November 12, 2020 4 hours ago, Zedna said: As I said: inside of loop use $tab (not @TAB) if speed is the need, you need to pull out all the (tab) stops $start = TimerInit() For $i = 1 To 100000 $s = "1" & Chr(9) Next ConsoleWrite("Chr(9): " & TimerDiff($start) & @CRLF) $start = TimerInit() For $i = 1 To 100000 $s = "1" & @TAB Next ConsoleWrite("@TAB: " & TimerDiff($start) & @CRLF) $start = TimerInit() $tab = @TAB For $i = 1 To 100000 $s = "1" & $tab Next ConsoleWrite("$tab: " & TimerDiff($start) & @CRLF) $start = TimerInit() For $i = 1 To 100000 $s = "1" & " " Next ConsoleWrite("Literal TAB: " & TimerDiff($start) & @CRLF) #cs Chr(9): 91.5255 @TAB: 103.4114 $tab: 60.7188 Literal: 55.084 #ce Code hard, but don’t hard code... Link to comment Share on other sites More sharing options...
Nine Posted November 13, 2020 Share Posted November 13, 2020 There is a potential bug with the code using StringLeft. If $iTabLen is greater than 8, it will not work correctly as the number of spaces provided in StringLeft is 8. Either the number should be increase, or a check should be made before calling the _TabsToSpaces function (not inside cause it will impact performance). “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Gianni Posted November 19, 2020 Share Posted November 19, 2020 (edited) On 10/26/2020 at 7:02 PM, Professor_Bernd said: Excuse my poor English. Was my formulation wrong? Is this formulation better? What I meant was a function with a reverse conversion direction. If the normal direction is to convert tabs to spaces, then the reverse direction would be to convert spaces to tabs. I think your function is more an undo function than a converter function SpacesToTabs. Hi @Professor_Bernd, the following function (_StringSpacesToTab) should work for that case. Here too, as already said, the TabLen parameter is important to obtain the correct result relative to the TabLens of the environment in which the resulting string will be used.Also, if the input string already contains some @tabs, this function fails, so it would be better to pass the string to the TabsToSpace function first in order to convert any @tabs to spaces before submitting it to this SpacesToTabs function (I hope there are no errors ) Here we go... expandcollapse popup#include <string.au3> _Example() Func _Example() Local $sMyString = "1 2 3 4" ; <--- random string that contains spaces ConsoleWrite($sMyString & @CRLF) ; we use 8 as second parametre because the AutoIt console has a Tablen of 8 as well ConsoleWrite(_StringSpacesToTabs($sMyString, 8) & @CRLF) ; <- contains @tabs (and residual spaces) ; - NOTE - ; ------------------------------------------------------------------------------------------------- ; If input strings contains some @tab, the _StringSpacesToTabs() function fails ; so you should call it like this: _StringSpacesToTabs(_StringTabsToSpaces($sMyString)) so to ensure ; that no @tabs are contained in the input string. ; ------------------------------------------------------------------------------------------------- ; example ConsoleWrite(@CRLF & @CRLF & "... if input string contains also some @tabs ..." & @CRLF) $sMyString = @TAB & "Hello " & @TAB & "Good " & @TAB & "Morning <" ; <--- contains spaces and @tab ConsoleWrite($sMyString & @CRLF) ; first convert @tabs to spaces (if any), then convert spaces to @tabs ConsoleWrite(_StringSpacesToTabs(_StringTabsToSpaces($sMyString, 8), 8) & @CRLF) EndFunc ;==>_Example Func _StringSpacesToTabs($sInput, $iTabLen = 8) Local Static $iTab = @TAB, $sSpc = ' ' Local $i1 = StringLen($sInput) ; start from the last char of the string While $i1 ; Check if there is a space before a TabStop position While (StringMid($sInput, $i1, 1) == $sSpc) And (Mod($i1, $iTabLen) = 0) $iStartSpaces = $i1 ; if so then remember this 'start' position ... ; ... and search for any additional spaces (only up to tablen) While (StringMid($sInput, $i1 - 1, 1) == $sSpc) And (Mod($i1 - 1, $iTabLen)) $i1 -= 1 WEnd ; remove found spaces from the string and replace with a @tab $sInput = StringLeft($sInput, $i1 - 1) & $iTab & StringMid($sInput, $iStartSpaces + 1) WEnd ; go to check next char (backwards) $i1 -= 1 WEnd Return $sInput EndFunc ;==>_StringSpacesToTabs Func _StringTabsToSpaces($sString, $iTabLen = 8) Local Static $iTab = @TAB, $sSpc = ' ' Local $iMod, $iSpaceLeft Local $iTabPos = StringInStr($sString, $iTab, 1) While $iTabPos $iMod = Mod($iTabPos, $iTabLen) $iSpaceLeft = $iMod ? $iTabLen - $iMod : 0 $sString = StringReplace($sString, $iTab, _StringRepeat($sSpc, $iSpaceLeft + 1), 1, 1) $iTabPos = StringInStr($sString, $iTab, 1) WEnd Return $sString EndFunc ;==>_StringTabsToSpaces Edited November 19, 2020 by Chimp renamed Function from _StringSpacesToTab to _StringSpacesToTabs Professor_Bernd 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
Professor_Bernd Posted November 19, 2020 Author Share Posted November 19, 2020 Hello Chimp. At the moment I am very busy with my project PSPad4AutoIt3 (editor IDE), for which I try to release the next version before the end of the year. Therefore I could only test your code for a short time. Your code is cool! I didn't think that the reverse direction, meaning SpacesToTabs would be possible in a useful way. But you have found a solution! Even though there are probably few situations to use this direction, it is always better to have a solution and not need it than to need a solution and not have it. Therefore: Good work! I thank you! Link to comment Share on other sites More sharing options...
Gianni Posted November 19, 2020 Share Posted November 19, 2020 11 minutes ago, Professor_Bernd said: ... I didn't think that the reverse direction, meaning SpacesToTabs would be possible in a useful way. me too, it's not that easy to find in fact, that's why I wanted to find it ... 15 minutes ago, Professor_Bernd said: it is always better to have a solution and not need it than to need a solution and not have it I agree ... 15 minutes ago, Professor_Bernd said: I thank you! You are welcome.. Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... 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