TheSaint Posted December 9, 2019 Share Posted December 9, 2019 (edited) _ReadIniSectionNames is just a little function I whipped up, that I thought I might as well share ... someone might find it useful. I had a need for it due to approaching the 32767 characters limit with the original INI function - IniReadSectionNames (see the Help file if you are not aware of this). Enjoy! Others have been there before me, and no doubt many others have also crafted their own solutions. Here is two old ones I found with a quick search ... both different but kind of similar to mine. I've gone for the simplistic approach. Test Example.au3 NOTE - It should be obvious you need to provide your own INI file and its correct path for the $file variable. #include <Array.au3> #include "ReadIniSectionNames.au3" Local $file = @ScriptDir & "\Settings.ini" Local $names = _ReadIniSectionNames($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Exit ReadIniSectionNames.au3 Global $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt, $SectionNames Func _ReadIniSectionNames($INIfile) $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Edited December 9, 2019 by TheSaint coffeeturtle and Inpho 2 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
TheSaint Posted December 10, 2019 Author Share Posted December 10, 2019 (edited) It has been suggested to me, that making $SectionNames an array at the start, and then adding to it, would be faster than concatenating strings and using StringSplit. I did not find that to be the case, and doing so was actually significantly slower ... but maybe I am doing it wrong? Here is what I did, with a 1.09 Mb INI file, that contains 2136 sections. expandcollapse popup#include <Array.au3> Global $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt Local $file = "D:\Programs\KindEbook Wishlist\Jumbo (b).ini" Local $names = _ReadIniSectionNames($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Local $names = _ReadIniSectionNames_2($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Exit Func _ReadIniSectionNames($INIfile) Local $begin, $diff, $SectionNames $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $begin = TimerInit() $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) $diff = TimerDiff($begin) & " milliseconds" $diff = "Using StringSplit = " & $diff ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func _ReadIniSectionNames_2($INIfile) Local $begin, $diff_2, $s $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $begin = TimerInit() Local $SectionNames[1] $s = 0 For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $s = $s + 1 _ArrayAdd($SectionNames, $INIsection, 1) EndIf EndIf Next If $s = 0 Then Return SetError(2, 0, -2) Else $SectionNames[0] = $s $diff_2 = TimerDiff($begin) & " milliseconds" $diff_2 = "Using _ArrayAdd = " & $diff_2 $diff = ClipGet() & @LF & $diff_2 ClipPut($diff) MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_2 Here are some timing results. None are the same, no doubt due to vagaries of my PC and while connected to the web. Using StringSplit = 475.797265465162 milliseconds Using _ArrayAdd = 6029.33782085074 milliseconds Using StringSplit = 469.701270439278 milliseconds Using _ArrayAdd = 6282.41561636396 milliseconds Using StringSplit = 500.060210392314 milliseconds Using _ArrayAdd = 6137.26802103186 milliseconds Using StringSplit = 484.184327357759 milliseconds Using _ArrayAdd = 6135.25773119869 milliseconds Using StringSplit = 489.524006129172 milliseconds Using _ArrayAdd = 6130.73949420813 milliseconds Edited December 10, 2019 by TheSaint coffeeturtle 1 Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
TheDcoder Posted December 10, 2019 Share Posted December 10, 2019 2 hours ago, TheSaint said: It has been suggested to me, that making $SectionNames an array at the start, and then adding to it, would be faster than concatenating strings and using StringSplit. Whoever said that is silly, any coder with half a brain would know that resizing an array is heaps slower than concatenating a string Anyway, I improved your function by using an Array, but in a different and more efficient way: expandcollapse popup#include <Array.au3> #include <StringConstants.au3> Global $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt, $SectionNames Example() Func Example() Local $aSections = _ReadIniSectionNames("Test.ini") _ArrayDisplay($aSections) EndFunc Func _ReadIniSectionNames($INIfile) $INIread = FileRead($INIfile) Local $iSectionCount = StringCount($INIread, '[') Local $aSections[$iSectionCount + 1] $aSections[0] = 0 $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $aSections[0] += 1 $aSections[$aSections[0]] = $INIsection EndIf EndIf Next If $aSections[0] = 0 Then Return SetError(2, 0, -2) Else If $aSections[0] < $iSectionCount Then ReDim $aSections[$aSections[0] + 1] Return $aSections EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func StringCount($sMasterString, $sString) Local $iPos = 0 Local $iCount = 0 While True $iPos = StringInStr($sMasterString, $sString, $STR_NOCASESENSEBASIC, 1, $iPos + 1) If @error Or $iPos = 0 Then ExitLoop $iCount += 1 WEnd Return $iCount EndFunc coffeeturtle 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
TheDcoder Posted December 10, 2019 Share Posted December 10, 2019 Another point, someone might think that my StringCount function is not correct for detecting the number of sections in the file... and they would be right, it is just an approxmation, not an absolute value of the number of sections in the INI file. As everyone knows how high my coding standards are, I have obviously accounted for the possibility of an over-estimation, so an INI file with these contents would still work: [Foobar1] error=[ [Foobar2] [Foobar3] EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
TheSaint Posted December 10, 2019 Author Share Posted December 10, 2019 (edited) Okay, adding in TheDcoder's ReDim method ... with a slight adaption by me to match the other two etc. By the way, my INI file has increased to 2139 sections, since I last tested ... 3 acquisitions from Amazon. expandcollapse popup#include <Array.au3> #include <StringConstants.au3> Global $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt Local $file = "D:\Programs\KindEbook Wishlist\Jumbo (b).ini" Local $names = _ReadIniSectionNames($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Local $names = _ReadIniSectionNames_2($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Local $names = _ReadIniSectionNames_3($file) If Not @error Then _ArrayDisplay($names) Else MsgBox(0, "Return Error", $names) EndIf Exit Func _ReadIniSectionNames($INIfile) Local $begin, $diff, $SectionNames $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $begin = TimerInit() $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) $diff = TimerDiff($begin) & " milliseconds" $diff = "Using StringSplit = " & $diff ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func _ReadIniSectionNames_2($INIfile) Local $begin, $diff_2, $s $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $begin = TimerInit() Local $SectionNames[1] $s = 0 For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $s = $s + 1 _ArrayAdd($SectionNames, $INIsection, 1) EndIf EndIf Next If $s = 0 Then Return SetError(2, 0, -2) Else $SectionNames[0] = $s $diff_2 = TimerDiff($begin) & " milliseconds" $diff_2 = "Using _ArrayAdd = " & $diff_2 $diff = ClipGet() & @LF & $diff_2 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_2 Func _ReadIniSectionNames_3($INIfile) Local $begin, $diff_3 $INIread = FileRead($INIfile) Local $iSectionCount = StringCount($INIread, '[') Local $SectionNames[$iSectionCount + 1] $SectionNames[0] = 0 $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $begin = TimerInit() For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $SectionNames[0] += 1 $SectionNames[$SectionNames[0]] = $INIsection EndIf EndIf Next If $SectionNames[0] = 0 Then Return SetError(2, 0, -2) Else If $SectionNames[0] < $iSectionCount Then ReDim $SectionNames[$SectionNames[0] + 1] $diff_3 = TimerDiff($begin) & " milliseconds" $diff_3 = "Using ReDim = " & $diff_3 $diff = ClipGet() & @LF & $diff_3 ClipPut($diff) MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_3 Func StringCount($sMasterString, $sString) Local $iPos = 0 Local $iCount = 0 While True $iPos = StringInStr($sMasterString, $sString, $STR_NOCASESENSEBASIC, 1, $iPos + 1) If @error Or $iPos = 0 Then ExitLoop $iCount += 1 WEnd Return $iCount EndFunc Not much in it for all that extra brain work. Times are so variable. So as I am fond of saying - Simple is best. Using StringSplit = 455.895273238447 milliseconds Using _ArrayAdd = 6192.77094369345 milliseconds Using ReDim = 425.429429119466 milliseconds Using StringSplit = 476.165900520144 milliseconds Using _ArrayAdd = 7039.70260981331 milliseconds Using ReDim = 467.105465260447 milliseconds Using StringSplit = 540.775337823308 milliseconds Using _ArrayAdd = 8396.5929519435 milliseconds Using ReDim = 494.923895292899 milliseconds Using StringSplit = 795.332588690522 milliseconds Using _ArrayAdd = 6796.17676296643 milliseconds Using ReDim = 576.076445080135 milliseconds Using StringSplit = 470.990264348198 milliseconds Using _ArrayAdd = 7487.17702961245 milliseconds Using ReDim = 531.051359464644 milliseconds Edited December 10, 2019 by TheSaint Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
TheDcoder Posted December 10, 2019 Share Posted December 10, 2019 (edited) Those results are pretty wacky, AutoIt is performing some memory tradeoff to make string concatenation more efficient, which is good for people who want simple and fast code and don't mind some extra memory use. Anyway, the only remotely expensive operation in the timed parts of my code is the ReDim operation, which is only done once when the $iSectionCount guess is wrong (and it is right most of the time assuming not many INI files have the [ character as a value in one of their keys). The only other modification is: $SectionNames[0] += 1 $SectionNames[$SectionNames[0]] = $INIsection Which is supposed to be an almost instant operation, certainly when compared to string concatenation So there are other factors at play, and performance is not always reliable, especially when attempting to measure it according to my personal experience. In any case, my code doesn't depend on assumptions and trade-offs being made by the interperter (AutoIt) and it is pretty solid. Edited December 10, 2019 by TheDcoder TheSaint 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
jchd Posted December 10, 2019 Share Posted December 10, 2019 Passing nearby I can't resist pointing out that for such volume of data which will obviously have to be searched, most probably using various if not contrived ways/criterion, I'd use SQLite without one µsecond hesitation. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
TheDcoder Posted December 10, 2019 Share Posted December 10, 2019 41 minutes ago, jchd said: I'd use SQLite without one µsecond hesitation. TheSaint has already gone that route, but he prefers to stick to simpler INI functions as SQLite is complex and does not bode well with his mindset of simple programming as he explained here : EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
jchd Posted December 10, 2019 Share Posted December 10, 2019 That's a matter of taste, of course. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
argumentum Posted December 10, 2019 Share Posted December 10, 2019 I'd load the ini in a 3D array, with the 1 table ( $aArray[0][0][0] ) as the index (ReadIniSectionNames) , or load it to a script dictionary. That way you'd have the ini in memory and you could dump it to file as you go. Then again, SQLite ala ini functions can be coded but it would not be plain text. I use as a preference ini files but not as a database, I mean, 32k of initialization data !, that's more like a db !.Then again I look at @TheSaint's avatar and it's a beautiful sight. I have trouble with things that are not as I want'em. Bottom line: an INI file is for configuration/initialization, not a database nor meant as one. ( now that is harsh but I felt needed to be said ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Progh0st Posted December 12, 2019 Share Posted December 12, 2019 (edited) Simple and faster... expandcollapse popup#include <Array.au3> #include <StringConstants.au3> ;For $i = 1 To 1000 ; IniWrite("TestIni.ini", "Numbers " & $i, "Results " & $i, $i) ;Next $Path = "TestIni.ini" $time = TimerInit() MyIniReadSectionNames($Path) MsgBox(0,"","My Example: " & TimerDiff($time)) $time = TimerInit() _ReadIniSectionNamesTheSaint($Path) MsgBox(0,"","TheSaint Example: " & TimerDiff($time)) $time = TimerInit() _ReadIniSectionNamesTheDcoder($Path) MsgBox(0,"","TheDcoder Example: " & TimerDiff($time)) Func MyIniReadSectionNames($Path) FileReadToArray($Path) Local $Array[@extended/2] $File = FileRead($Path) If Not @error Then $Str = StringRegExp($File, "(?!\[).+(?=\])", 3) If IsArray($Str) Then For $i = 0 To UBound($Str)-1 $Array[$i] = $Str[$i] Next Return $Array EndIf EndIf EndFunc Func _ReadIniSectionNamesTheSaint($INIfile) $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func _ReadIniSectionNamesTheDcoder($INIfile) $INIread = FileRead($INIfile) Local $iSectionCount = StringCount($INIread, '[') Local $aSections[$iSectionCount + 1] $aSections[0] = 0 $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $aSections[0] += 1 $aSections[$aSections[0]] = $INIsection EndIf EndIf Next If $aSections[0] = 0 Then Return SetError(2, 0, -2) Else If $aSections[0] < $iSectionCount Then ReDim $aSections[$aSections[0] + 1] Return $aSections EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func StringCount($sMasterString, $sString) Local $iPos = 0 Local $iCount = 0 While True $iPos = StringInStr($sMasterString, $sString, $STR_NOCASESENSEBASIC, 1, $iPos + 1) If @error Or $iPos = 0 Then ExitLoop $iCount += 1 WEnd Return $iCount EndFunc Edited December 12, 2019 by Progh0st TheSaint 1 Link to comment Share on other sites More sharing options...
TheSaint Posted December 16, 2019 Author Share Posted December 16, 2019 On 12/11/2019 at 12:26 AM, argumentum said: Bottom line: an INI file is for configuration/initialization, not a database nor meant as one. ( now that is harsh but I felt needed to be said ) Well you say that, and it was certainly true once upon a time, but INI files can be quite huge now, and no longer limited like they used to be, and far easier to troubleshoot or apply a manual quick fix using a text editor. So I would say, if your database needs are simple, than INI is quite fine. If you want to do all sorts of fancy things then go SQL. If they ever bring out a database program that gives quick visual access and editing with Notepad, that is not INI and works better than INI ... and especially isn't XML ... then I would certainly be keen to give it a go. It must also support words that contain single and double quotes without having to do anything special. I was almost in love with SQL until I discovered blank database entries due an apostrophe in some entries, that I then had to code for to get around ... in what is supposedly a database program. I can almost accept the issue when it comes to program settings (INI file etc), but a true database language should accept apostrophes, which are as common as dog's balls, off the bat, without anything special needing to be done ... we are 2019 after all, nearly 2020 ... it shouldn't be required to use escape characters ... in fact if you want to use such characters as other than text, then a command should be required to specify so, not the other way around in this day and age ... but hey it is the digital age of the nerd ... so it will be a while yet before that idea finally catches on. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
TheSaint Posted December 16, 2019 Author Share Posted December 16, 2019 (edited) On 12/12/2019 at 11:18 AM, Progh0st said: Simple and faster... Not for me it wasn't, but thanks. I did a quick adaption of your code to add to my mix ... which included an adjustment to return the count in the first element of the array. I'm not sure if your code is taking into account that a '[' or ']' could exist beyond the section name ... RegEx is not a strong point of mine? Part of the reason your code takes so long to finish, is all the extra blank sections at the end, that get returned ... not sure what that is about ... maybe some null character? Of the non blanks, your code returns 2140 section names, when it should be 2139, but I discovered one (1797) was an entry not a section, and it contained a '[' and looked truncated. Quote title=Dead in Damascus: A Special Operations Group Short Story ([#0 Like you, I also changed where TimerInit() is used for each option. expandcollapse popup#include <Array.au3> #include <StringConstants.au3> Global $begin, $diff, $filepth, $i, $INIfile, $INIlines, $INIread, $INIsection, $linetxt $filepth = "D:\Programs\KindEbook Wishlist\Jumbo (b).ini" $begin = TimerInit() Local $names = _ReadIniSectionNames($filepth) ; TheSaint If Not @error Then _ArrayDisplay($names, "Using StringSplit") Else MsgBox(0, "Return Error", $names) EndIf $begin = TimerInit() Local $names = _ReadIniSectionNames_2($filepth) ; TheSaint If Not @error Then _ArrayDisplay($names, "Using _ArrayAdd") Else MsgBox(0, "Return Error", $names) EndIf $begin = TimerInit() Local $names = _ReadIniSectionNames_3($filepth) ; TheDcoder If Not @error Then _ArrayDisplay($names, "Using ReDim") Else MsgBox(0, "Return Error", $names) EndIf $begin = TimerInit() Local $names = _ReadIniSectionNames_4($filepth) ; Progh0st If Not @error Then _ArrayDisplay($names, "Using StringRegExp") Else MsgBox(0, "Return Error", $names) EndIf MsgBox(0, "Time Taken", $diff) Exit Func _ReadIniSectionNames($INIfile) Local $SectionNames $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else ;$begin = TimerInit() $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) $diff = TimerDiff($begin) & " milliseconds" $diff = "Using StringSplit = " & $diff ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func _ReadIniSectionNames_2($INIfile) Local $diff_2, $s $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else Local $SectionNames[1] $s = 0 For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $s = $s + 1 _ArrayAdd($SectionNames, $INIsection, 1) EndIf EndIf Next If $s = 0 Then Return SetError(2, 0, -2) Else $SectionNames[0] = $s $diff_2 = TimerDiff($begin) & " milliseconds" $diff_2 = "Using _ArrayAdd = " & $diff_2 $diff = ClipGet() & @LF & $diff_2 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_2 Func _ReadIniSectionNames_3($INIfile) Local $diff_3 $INIread = FileRead($INIfile) Local $iSectionCount = StringCount($INIread, '[') Local $SectionNames[$iSectionCount + 1] $SectionNames[0] = 0 $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $SectionNames[0] += 1 $SectionNames[$SectionNames[0]] = $INIsection EndIf EndIf Next If $SectionNames[0] = 0 Then Return SetError(2, 0, -2) Else If $SectionNames[0] < $iSectionCount Then ReDim $SectionNames[$SectionNames[0] + 1] $diff_3 = TimerDiff($begin) & " milliseconds" $diff_3 = "Using ReDim = " & $diff_3 $diff = ClipGet() & @LF & $diff_3 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_3 Func StringCount($sMasterString, $sString) Local $iPos = 0 Local $iCount = 0 While True $iPos = StringInStr($sMasterString, $sString, $STR_NOCASESENSEBASIC, 1, $iPos + 1) If @error Or $iPos = 0 Then ExitLoop $iCount += 1 WEnd Return $iCount EndFunc Func _ReadIniSectionNames_4($INIfile) Local $diff_4 FileReadToArray($INIfile) Local $Array[@extended/2] $INIread = FileRead($INIfile) If Not @error Then $Str = StringRegExp($INIread, "(?!\[).+(?=\])", 3) If IsArray($Str) Then $Array[0] = UBound($Str)-1 For $i = 0 To $Array[0] $Array[$i + 1] = $Str[$i] Next $diff_4 = TimerDiff($begin) & " milliseconds" $diff_4 = "Using StringRegExp = " & $diff_4 $diff = ClipGet() & @LF & $diff_4 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $Array Else Return SetError(2, 0, -2) EndIf Else Return SetError(1, 0, -1) EndIf EndFunc ;=> _ReadIniSectionNames_4 LOL, my computer has had a rest for 6 days, but I doubt that has had any impact on the following results ... unless extra services are running in the background doing update checks etc. Using StringSplit = 640.6785096822 milliseconds Using _ArrayAdd = 6454.83544745537 milliseconds Using ReDim = 1706.50690023384 milliseconds Using StringRegExp = 7994362.73136458 milliseconds Using StringSplit = 636.893856451052 milliseconds Using _ArrayAdd = 6528.23744521161 milliseconds Using ReDim = 1033.22200554673 milliseconds Using StringRegExp = 8221753.24552446 milliseconds Using StringSplit = 644.393122252901 milliseconds Using _ArrayAdd = 6502.97304171843 milliseconds Using ReDim = 1058.29471881132 milliseconds Using StringRegExp = 10782.6687457684 milliseconds Using StringSplit = 630.238764925112 milliseconds Using _ArrayAdd = 6401.26048613133 milliseconds Using ReDim = 1064.84413495484 milliseconds Using StringRegExp = 10225.6574913401 milliseconds Using StringSplit = 1042.68056666581 milliseconds Using _ArrayAdd = 6550.86549366992 milliseconds Using ReDim = 1044.97347670779 milliseconds Using StringRegExp = 10513.411557692 milliseconds Using StringSplit = 710.721013304039 milliseconds Using _ArrayAdd = 6613.37862629376 milliseconds Using ReDim = 1086.44492039326 milliseconds Using StringRegExp = 10129.1801679256 milliseconds The first block of 4 out of 6 results above, were done using the GO option in SciTE, the other (last) two were done executing the AU3 file. The following is a typical section in my test INI file. Quote [B00DMCPRQA] date=15/01/2015 6:46:08 PM url=http://www.amazon.com/dp/B00DMCPRQA/etc title=Stolen Crown: A Novel of Mithgar author=Dennis L. McKiernan start=$14.82 low=$6.39 high=$14.88 current=$6.39 query=17/05/2015 12:58:29 AM bought=Paid $6.39 on 17/05/2015 1:01:16 AM changed=17/05/2015 12:58:29 AM previous=24/02/2015 6:35:58 AM last=$6.39 Edited December 16, 2019 by TheSaint Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
argumentum Posted December 16, 2019 Share Posted December 16, 2019 10 hours ago, TheSaint said: if your database needs are simple ...I used to have a happy face DB. So it happens, chr(1) is a pappy face in Terminal font. the chr(2) is a color inverted happy face too. Those where the delimiters for my databaseish scheme. Read, split and was human readable. In your case, a TAB delimited table may be easier than an INI styled file. You can use the _array to/from file(). So it would meet your requirement of notepad editable database. Basically, if you can read/write to file, is the bases of holding data ( data base ). INI styled or what not is all the same in the case of notapad editable db As the DB grows, searching may need flexibility in querying the data. SQL92 was to get us all to agree but you are a one man team. I use ( at times ) what others came up with as a "ready made" solution, ex: SQLite. A blob in an INI file would take Str2Bin to keep it a one-liner. ok, new bottom line: Use industry standards or come up with your own. If is functional, it functioned. TheSaint 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
seadoggie01 Posted December 16, 2019 Share Posted December 16, 2019 (edited) While I don't have a 1 Mb Ini file to test it on, it looks like this RegEx is simpler and faster at least on smaller files (210 Kb) by ~20 milliseconds (with file handles or the file name) Func _Ini_ReadSectionNames($sFileName) ;~ If Not FileExists($sFileName) Then Return SetError(1, 0, False) Local $sContents = FileRead($sFileName) ; (?m) - Allows new lines to be used ; ^ - Starting at the beginning of a line ; \[ - Match an open square bracket ; ([^\]]+) - Capture everything that isn't a closing square bracket (at least 1 character) ; \] - Match a closing square bracket ; \s* - Match as much blank space as you need, Taylor ; $ - Match the end of a line Local $aSections = StringRegExp($sContents, "(?m)^\[([^\]]+)\]\s*$", 3) Return SetError(@error, @extended, $aSections) EndFunc I ran some tests, but I'm not the expert of giant files Edit: Just realized that you return a 1-based array. Mine's 0-based (personal preference, it's in my ini file). It also works with brackets strewn about in the data. Edited December 16, 2019 by seadoggie01 TheSaint 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
TheDcoder Posted December 17, 2019 Share Posted December 17, 2019 Spoiler Quote Using StringSplit = 640.6785096822 milliseconds Using _ArrayAdd = 6454.83544745537 milliseconds Using ReDim = 1706.50690023384 milliseconds Using StringRegExp = 7994362.73136458 milliseconds Using StringSplit = 636.893856451052 milliseconds Using _ArrayAdd = 6528.23744521161 milliseconds Using ReDim = 1033.22200554673 milliseconds Using StringRegExp = 8221753.24552446 milliseconds Using StringSplit = 644.393122252901 milliseconds Using _ArrayAdd = 6502.97304171843 milliseconds Using ReDim = 1058.29471881132 milliseconds Using StringRegExp = 10782.6687457684 milliseconds Using StringSplit = 630.238764925112 milliseconds Using _ArrayAdd = 6401.26048613133 milliseconds Using ReDim = 1064.84413495484 milliseconds Using StringRegExp = 10225.6574913401 milliseconds Using StringSplit = 1042.68056666581 milliseconds Using _ArrayAdd = 6550.86549366992 milliseconds Using ReDim = 1044.97347670779 milliseconds Using StringRegExp = 10513.411557692 milliseconds Using StringSplit = 710.721013304039 milliseconds Using _ArrayAdd = 6613.37862629376 milliseconds Using ReDim = 1086.44492039326 milliseconds Using StringRegExp = 10129.1801679256 milliseconds Good to see that my Array approach ins't falling behind too much with a consistent 2nd position Also surprised to see that RegEx is slower than _ArrayAdd TheSaint 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion Link to comment Share on other sites More sharing options...
TheSaint Posted December 17, 2019 Author Share Posted December 17, 2019 2 hours ago, TheDcoder said: Good to see that my Array approach ins't falling behind too much with a consistent 2nd position Also surprised to see that RegEx is slower than _ArrayAdd Yep, you did good bud. I suspect the StringRegEx is returning every line of my INI file, but only the lines with the actual section name (plus one other) have visible values. So clearly to my mind at least, the RegEx is wrong. @seadoggie01 has probably given the correct one. I will test that a bit later. Need to put my legs up, the holiday was physically tough on me in a number of ways leg related especially. Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
Progh0st Posted December 20, 2019 Share Posted December 20, 2019 (edited) On 12/16/2019 at 3:19 AM, TheSaint said: Not for me it wasn't, but thanks. I did a quick adaption of your code to add to my mix ... which included an adjustment to return the count in the first element of the array. I'm not sure if your code is taking into account that a '[' or ']' could exist beyond the section name ... RegEx is not a strong point of mine? Part of the reason your code takes so long to finish, is all the extra blank sections at the end, that get returned ... not sure what that is about ... maybe some null character? Of the non blanks, your code returns 2140 section names, when it should be 2139, but I discovered one (1797) was an entry not a section, and it contained a '[' and looked truncated. try this: Func MyIniReadSectionNames($Path) $File = FileRead($Path) If Not @error Then $Str = StringRegExp($File, "(?m)^\[{1}([^\[\]]+)\]{1}", 3) If IsArray($Str) Then $ArraySize = UBound($Str) Local $Array[$ArraySize] For $i = 0 To $ArraySize-1 $Array[$i] = $Str[$i] Next Return $Array EndIf EndIf EndFunc It will match anything between [....] For Section names only. Hopefully. Test speed please 😃 A little faster, using it directly like (seadoggie01) Func MyIniReadSectionNames($Path) $File = FileRead($Path) If Not @error Then $Str = StringRegExp($File, "(?m)^\[{1}([^\[\]]+)\]{1}", 3) If IsArray($Str) Then Return $Str EndIf EndIf EndFunc Edited December 23, 2019 by Progh0st TheSaint 1 Link to comment Share on other sites More sharing options...
TheSaint Posted December 22, 2019 Author Share Posted December 22, 2019 (edited) Okay, I finally got a moment to test the last two methods ... and wow. Quote (TheSaint) - Using StringSplit = 684.060711735989 milliseconds (TheSaint) - Using _ArrayAdd = 7170.40892686649 milliseconds (TheDcoder) - Using ReDim = 1162.42674914262 milliseconds (Progh0st) - Using StringRegExp = 256.445891132238 milliseconds (seadoggie01) - Using StringRegExp_2 = 280.931245875895 milliseconds @Progh0st appears to be the winner, with @seadoggie01 not far behind. Bad luck @TheDcoder looks like you and I are out in the cold. Here are the amended methods ... five in all. My INI file has also increased to 2241 sections. expandcollapse popup#include <Array.au3> #include <StringConstants.au3> #include <File.au3> Global $begin, $diff, $error, $filepth, $i, $INIfile, $INIlines, $INIread Global $INIsection, $linetxt, $method, $names, $next ; Current sections = 2241 $filepth = "D:\Programs\KindEbook Wishlist\Jumbo (b).ini" If FileExists($filepth) Then $diff = "" ClipPut($diff) $method = "StringSplit" While 1 $error = "" StartFresh() If $method = "StringSplit" Then $names = _ReadIniSectionNames($filepth) ; TheSaint If @error Then $error = 1 $next = "_ArrayAdd" ElseIf $method = "_ArrayAdd" Then $names = _ReadIniSectionNames_2($filepth) ; TheSaint If @error Then $error = 1 $next = "ReDim" ElseIf $method = "ReDim" Then $names = _ReadIniSectionNames_3($filepth) ; TheDcoder If @error Then $error = 1 $next = "StringRegExp" ElseIf $method = "StringRegExp" Then $names = _ReadIniSectionNames_4($filepth) ; Progh0st If @error Then $error = 1 $next = "StringRegExp_2" ElseIf $method = "StringRegExp_2" Then $names = _Ini_ReadSectionNames_5($filepth) ; seadoggie01 If @error Then $error = 1 $next = "" EndIf If $error = 1 Then MsgBox(0, "Return Error", $names) Else _ArrayDisplay($names, "Using " & $method) EndIf If $next = "" Then ExitLoop $method = $next WEnd MsgBox(0, "Time Taken", $diff) Else MsgBox(0, "Source Error", "INI file path not found!") EndIf Exit Func StartFresh() $begin = TimerInit() $names = "" $INIread = "" $INIlines = "" $INIsection = "" EndFunc ;=> StartFresh Func _ReadIniSectionNames($INIfile) ; TheSaint Local $SectionNames $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else $SectionNames = "" For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then If $SectionNames = "" Then $SectionNames = $INIsection Else $SectionNames = $SectionNames & "|" & $INIsection EndIf EndIf EndIf Next If $SectionNames = "" Then Return SetError(2, 0, -2) Else $SectionNames = StringSplit($SectionNames, "|", 1) $diff = TimerDiff($begin) & " milliseconds" $diff = "Using StringSplit = " & $diff ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames Func _ReadIniSectionNames_2($INIfile) ; TheSaint Local $diff_2, $s $INIread = FileRead($INIfile) $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else Local $SectionNames[1] $s = 0 For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $s = $s + 1 _ArrayAdd($SectionNames, $INIsection, 1) EndIf EndIf Next If $s = 0 Then Return SetError(2, 0, -2) Else $SectionNames[0] = $s $diff_2 = TimerDiff($begin) & " milliseconds" $diff_2 = "Using _ArrayAdd = " & $diff_2 $diff = ClipGet() & @LF & $diff_2 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_2 Func _ReadIniSectionNames_3($INIfile) ; TheDcoder Local $diff_3 $INIread = FileRead($INIfile) Local $iSectionCount = StringCount($INIread, '[') Local $SectionNames[$iSectionCount + 1] $SectionNames[0] = 0 $INIlines = StringSplit($INIread, @LF, 1) If @error Then Return SetError(1, 0, -1) Else For $i = 1 To $INIlines[0] $linetxt = $INIlines[$i] If StringLeft($linetxt, 1) = "[" Then $INIsection = StringTrimLeft($linetxt, 1) $INIsection = StringStripCR($INIsection) $INIsection = StringTrimRight($INIsection, 1) If $INIsection <> "" Then $SectionNames[0] += 1 $SectionNames[$SectionNames[0]] = $INIsection EndIf EndIf Next If $SectionNames[0] = 0 Then Return SetError(2, 0, -2) Else If $SectionNames[0] < $iSectionCount Then ReDim $SectionNames[$SectionNames[0] + 1] $diff_3 = TimerDiff($begin) & " milliseconds" $diff_3 = "Using ReDim = " & $diff_3 $diff = ClipGet() & @LF & $diff_3 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames EndIf EndIf EndFunc ;=> _ReadIniSectionNames_3 Func StringCount($sMasterString, $sString) Local $iPos = 0 Local $iCount = 0 While True $iPos = StringInStr($sMasterString, $sString, $STR_NOCASESENSEBASIC, 1, $iPos + 1) If @error Or $iPos = 0 Then ExitLoop $iCount += 1 WEnd Return $iCount EndFunc Func _ReadIniSectionNames_4($INIfile) ; Progh0st Local $ArraySize, $diff_4, $Str $INIread = FileRead($INIfile) If Not @error Then $Str = StringRegExp($INIread, "(?m)^\[{1}([^\[\]]+)\]{1}", 3) If IsArray($Str) Then $ArraySize = UBound($Str) Local $Array[$ArraySize + 1] For $i = 0 To $ArraySize - 1 $Array[$i + 1] = $Str[$i] Next $Array[0] = UBound($Array) - 1 $diff_4 = TimerDiff($begin) & " milliseconds" $diff_4 = "Using StringRegExp = " & $diff_4 $diff = ClipGet() & @LF & $diff_4 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $Array Else Return SetError(2, 0, -2) EndIf Else Return SetError(1, 0, -1) EndIf EndFunc ;=> _ReadIniSectionNames_4 Func _Ini_ReadSectionNames_5($INIfile) ; seadoggie01 Local $diff_5, $SectionNames ; (?m) - Allows new lines to be used ; ^ - Starting at the beginning of a line ; \[ - Match an open square bracket ; ([^\]]+) - Capture everything that isn't a closing square bracket (at least 1 character) ; \] - Match a closing square bracket ; \s* - Match as much blank space as you need, Taylor ; $ - Match the end of a line $INIread = FileRead($INIfile) If Not @error Then $SectionNames = StringRegExp($INIread, "(?m)^\[([^\]]+)\]\s*$", 3) $ArraySize = UBound($SectionNames) _ArrayInsert($SectionNames, 0, $ArraySize, 0) $diff_5 = TimerDiff($begin) & " milliseconds" $diff_5 = "Using StringRegExp_2 = " & $diff_5 $diff = ClipGet() & @LF & $diff_5 ClipPut($diff) ;MsgBox(0, "Time Taken", $diff) Return $SectionNames Else Return SetError(1, 0, -1) EndIf EndFunc ;=> _ReadIniSectionNames_5 A few more run through results. Quote Using StringSplit = 807.637626825819 milliseconds Using _ArrayAdd = 7831.22166886005 milliseconds Using ReDim = 1129.22870487446 milliseconds Using StringRegExp = 260.368168117246 milliseconds Using StringRegExp_2 = 277.868502960754 milliseconds Using StringSplit = 806.031606769614 milliseconds Using _ArrayAdd = 7577.08711952254 milliseconds Using ReDim = 1693.85227318807 milliseconds Using StringRegExp = 263.037700307073 milliseconds Using StringRegExp_2 = 516.418390957136 milliseconds Using StringSplit = 1220.27296197038 milliseconds Using _ArrayAdd = 6791.55469376872 milliseconds Using ReDim = 1154.44149945995 milliseconds Using StringRegExp = 277.211103779369 milliseconds Using StringRegExp_2 = 266.611617165123 milliseconds Using StringSplit = 670.33335668022 milliseconds Using _ArrayAdd = 7214.99595115831 milliseconds Using ReDim = 1135.47891223168 milliseconds Using StringRegExp = 265.972035344729 milliseconds Using StringRegExp_2 = 266.983324178896 milliseconds Using StringSplit = 844.649200737762 milliseconds Using _ArrayAdd = 6827.6624974042 milliseconds Using ReDim = 1132.80938004185 milliseconds Using StringRegExp = 253.72966516878 milliseconds Using StringRegExp_2 = 263.708001715382 milliseconds Using StringSplit = 1098.22465357521 milliseconds Using _ArrayAdd = 7380.63596919685 milliseconds Using ReDim = 1084.97406652388 milliseconds Using StringRegExp = 263.821664190668 milliseconds Using StringRegExp_2 = 269.532435584096 milliseconds The first 3 results were using the GO option in SciTE The next two results were executing the AU3 file. The last two results were executing the compiled AU3 file. Still a bit of variation between runs, but not as much with the StringRegExp methods. Edited December 22, 2019 by TheSaint Make sure brain is in gear before opening mouth! Remember, what is not said, can be just as important as what is said. Spoiler What is the Secret Key? Life is like a Donut If I put effort into communication, I expect you to read properly & fully, or just not comment. Ignoring those who try to divert conversation with irrelevancies. If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it. I'm only big and bad, to those who have an over-active imagination. I may have the Artistic Liesense to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage) Link to comment Share on other sites More sharing options...
TheDcoder Posted December 22, 2019 Share Posted December 22, 2019 17 minutes ago, TheSaint said: @Progh0st appears to be the winner, with @seadoggie01 not far behind. Bad luck @TheDcoder looks like you and I are out in the cold. Indeed, there is good reason why RegEx is faster, it has less overhead processing strings as it runs in pure machine code, so we cannot compare both methods really. If everything is written in a low-level language, my method would be fastest... a lot faster than RegEx EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion 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