 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 7:25 pm Post subject: |
|
|
| Titan wrote: | | and since you use file functions at every call |
---> manual <---
| Quote: | | According to my tests yours is 35% slower on average |
I don't think so, ofc, according to my tests
with ini files ?
... wha ? ... you have 10MB ini ?
| Quote: | | Maybe this is a good thing, those who are used to a structured and procedural way of accessing data would use my library whereas the casual user may find yours a little easier to learn. |
Maybe this is about AHK.
Anyway, the bigest difference is that your model is closed, while mine is open. You can preprocess sections with anything you want, while in your model every operation on Ini entitiy is done using your API. This feature is very convenient when changing large number of variables as you don't actually need to access them 1 by 1 in loop but you can change them all with your processor (like RE), ofc, if you keep them in section format. _________________
 |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5049 Location: imaginationland
|
Posted: Wed Dec 19, 2007 7:53 pm Post subject: |
|
|
| majkinetor wrote: | | Titan wrote: | | and since you use file functions at every call |
---> manual <--- | What does that show? All your functions either FileRead every time or loop for A_LoopFileLongPath which is then passed onto a WinAPI function that essentially FileReads internally.
| majkinetor wrote: | | ... wha ? ... you have 10MB ini ? | Hypothetically speaking of course. I do have megabytes of XML to parse routinely and if your library can't efficiently manage relatively large data sets it's obviously flawed by design.
| majkinetor wrote: | | Maybe this is about AHK. | How so?
| majkinetor wrote: | | Anyway, the bigest difference is that your model is closed, while mine is open. | Yes, I did just say "those who are used to a structured and procedural way of accessing data would use my library whereas the casual user may find yours a little easier to learn." Your functions create global variables which breaks a fundamental guideline of the stdlib for many reasons.
| majkinetor wrote: | I don't think so, ofc, according to my tests  | I question your benchmarking methods, take a look at my findings:
| Code: | ; prerequisites:
Process, Priority, , R ; highest priority
SetBatchLines, -1 ; no artificial delays
p = %ProgramFiles%\PHP\php.ini ; path to INI file
t0 := t1 := t2 := 0x00000000 ; initialize counters
ini_Load(obj, p) ; load file for my library
i = 100 ; iterations
; main test: (note this can take a while!)
DllCall("QueryPerformanceCounter", "Int64P", t0)
Loop, %i%
ini_GetKeys(obj, "PHP")
DllCall("QueryPerformanceCounter", "Int64P", t1)
Loop, %i%
ini_LoadKeys(p, "PHP")
DllCall("QueryPerformanceCounter", "Int64P", t2)
; calc. results:
DllCall("QueryPerformanceFrequency", "Int64P", f)
MsgBox, , Benchmarks, % "Titan:`t" . (a1 := t1 - t0) / f
. "`nmaji:`t" . (a2 := t2 - t1) / f
. "`n`n1st method is " . Round((a2 - a1) / a2 * 100, 2) . "% faster."
ExitApp
; include majkinetors functions, mine in stdlib
#Include C:\Users\Admin\AppData\Local\Temp\m_Ini.ahk |
Results:
| Code: | ---------------------------
Benchmarks
---------------------------
Titan: 0.036813
maji: 2.407354
1st method is 98.47% faster.
---------------------------
OK
--------------------------- |
When using ini_GetSections(obj) and ini_GetSectionNames(p) in each loop respectively and stepping up the iteration count to 1000 I get:
| Code: | ---------------------------
Benchmarks
---------------------------
Titan: 1.195974
maji: 1.931028
1st method is 38.07% faster.
---------------------------
OK
--------------------------- |
_________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 9:06 pm Post subject: |
|
|
You forced it to read from file every time and to create global variables every time, which is not the same as what your call above does. Instead:
| Code: | c := ini_LoadSection(p, "PHP") ;read section once.
...
ini_LoadKeys("",c, 1) ;return only key names (RTFM) |
Check this out:
| Code: | ; prerequisites:
Process, Priority, , R ; highest priority
SetBatchLines, -1 ; no artificial delays
p = wincmd.ini ; path to INI file
t0 := t1 := t2 := 0x00000000 ; initialize counters
ini_Load(obj, p) ; load file for my library
c := ini_LoadSection(p, "Configuration")
i = 100 ; iterations
; main test: (note this can take a while!)
DllCall("QueryPerformanceCounter", "Int64P", t0)
Loop, %i%
ini_Read(obj, "Configuration", "InstallDir")
DllCall("QueryPerformanceCounter", "Int64P", t1)
Loop, %i%
Ini_GetVal(c, "InstallDir")
DllCall("QueryPerformanceCounter", "Int64P", t2)
; calc. results:
DllCall("QueryPerformanceFrequency", "Int64P", f)
MsgBox, , Benchmarks, % "Titan:`t" . (a1 := t1 - t0) / f
. "`nmaji:`t" . (a2 := t2 - t1) / f
. "`n`n1st method is " . Round((a2 - a1) / a2 * 100, 2) . "% faster."
ExitApp
#Include Ini.ahk
#Include tIni.ahk |
| Code: | ---------------------------
Benchmarks
---------------------------
Titan: 0.003387
maji: 0.002536
1st method is -33.56% faster.
---------------------------
OK
--------------------------- |
It is faster
| Quote: | | When using ini_GetSections(obj) and ini_GetSectionNames(p) ... |
This is not real test. First, functionality is not the same. Your object has no connection to real state of the file once its loaded so changing the ini would not be seen by it until it is reloaded. Also, I stated many times, this function may allow itself to read from HD every time as nobody normal would call it 10000 times in the loop. You call it just once, get the sections and live happily ever after.
Artifical. _________________

Last edited by majkinetor on Wed Dec 19, 2007 9:53 pm; edited 2 times in total |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 9:27 pm Post subject: |
|
|
| Quote: | | Your functions create global variables which breaks a fundamental guideline of the stdlib for many reasons. |
You don't have to create any variable if you don't want to. Check out available flags .
| Quote: | | Hypothetically speaking of course. I do have megabytes of XML to parse routinely and if your library can't efficiently manage relatively large data sets it's obviously flawed by design. |
Specialized applications should implement their own seeking method. This is not created as a database engine, but as a set of helper functions for everyday use. Even in high-end IDEs you have to replace integrated memory managers and similar if you want to achive top-speed. When speaking about every day use, your approach is overkill and doesn't offer any of the benefits your script may provide for very large data handling scenarios. The point of my script was to minimize the amount of time you spend handling normal configuration files and variable sets,and to be able to use that mechanism on normal places, where extreme data flow is not present.
Here is another benchmark, this time:
| Code: | Loop, %i%
ini_Load(obj, p) ; load file for my library
Loop, %i%
Ini_LoadSection(p) |
| Code: | ---------------------------
Benchmarks
---------------------------
Titan: 8.780178
maji: 1.777333
1st method is -394.01% faster.
---------------------------
OK
---------------------------
|
_________________
 |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5049 Location: imaginationland
|
Posted: Wed Dec 19, 2007 9:50 pm Post subject: |
|
|
That is also an awkward test since your ini_LoadSection function saves a portion of the INI to memory, thus breaking HD sync contrary to what you "stated many times." Perhaps I didn't study your script well enough to realize they're incomparable given their nature of design. Nevertheless ini_GetSections(obj) vs. ini_GetSectionNames(p) were the most similar and mine was 35-40% faster, proving that string functions beat WinAPI coupled with regex when used properly, as if it wasn't obvious enough.
Ironically v1.0x of my library doesn't employ any real optimizations as it only uses primitive string searching. It would be interesting to see the results when such techniques are really implemented. However as you've duly noted speed should not be a primary concern, and imo. accessibility is more important, which is why ini_FindSectionsRE and ini_ToXML are the focus of the latest release (can yours do that? ).
As I said right in the beginning our libraries have different appeals, and the a difference with us is that I used your scripts for a period of time before I saw it lacked too much of what was needed. _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 9:58 pm Post subject: |
|
|
| Quote: | | Nevertheless ini_GetSections(obj) vs. ini_GetSectionNames(p) were the most similar and mine was 35-40% faster, proving that string functions beat WinAPI coupled with regex when used properly, as if it wasn't obvious enough. |
It doesn't prove anything as your version has no connection to the real world. Why should I call your function billion times just to get the same string again.
| Quote: | | ini_FindSectionsRE and ini_ToXML are the focus of the latest release (can yours do that? ). |
You can find section by using re on string returned by GetSectionNames function. The RE is simple, thus no reason to be function and quick 1s solution would be:
| Code: | | Ini_LoadKeys("", RegExReplace( Ini_GetSectionNames("wincmd.ini"), "`aim)^RE$", "$0="), "keys") |
About ini_ToXML, congratz !  _________________
 |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5049 Location: imaginationland
|
Posted: Wed Dec 19, 2007 10:16 pm Post subject: |
|
|
Sure, you could go on arguing that stats are meaningless but it's evident - string manipulation can be very efficient. Why else do you think pcre/perl was invented.
| majkinetor wrote: | | Ini_LoadKeys("", RegExReplace( Ini_GetSectionNames("wincmd.ini"), "`aim)^RE$", "$0="), "keys") | We must have very different viewpoints; a helper library in my opinion should facilitate common tasks like this with ease, hence ini_FindSectionsRE. _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 10:58 pm Post subject: |
|
|
| Quote: | | We must have very different viewpoints; a helper library in my opinion should facilitate common tasks like this with ease, hence ini_FindSectionsRE. |
The point was to see how quickly you can use INI functions on regular bases. There are countless examples, this is only one. You can always wrap above code if you need it much as I don't think that such operation is common.
The difference in our viewpoints is only that you are thinking with database model in mind, while I don't.
| Quote: | | Your functions create global variables which breaks a fundamental guideline of the stdlib for many reasons. |
Your function creates global variable at all cases, which can also be altered.
| Quote: |
That is also an awkward test since your ini_LoadSection function saves a portion of the INI to memory, thus breaking HD sync contrary to what you "stated many times." |
It accutaly doesn't (p is string containing real ini path, LoadSection always read the file). It reads the ini each time in that example, entire ini and all sections similar to what your Load does, just keeps data differently.
If you refer to the part where section is updated, you can make sure you are using the latest section if you reload just that section with LoadSections(ini, section). Its faster then creating entire structure you need for your obj every time.
Also, there is that little thing that I don't acctually might need all sections from the INI, some might be useful only for some script states which may never appear in the app in particular case. Hense, you can dealy loading of some section for the sake of the faster startup, until you actually need them.
As you see, our modules, like i told you, are very different.
Anyway, I didn't want to argue, just wanted to report the bug and ask for namechange. Nothing more  _________________
 |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5049 Location: imaginationland
|
Posted: Wed Dec 19, 2007 11:18 pm Post subject: |
|
|
| majkinetor wrote: | | The point was to see how quickly you can use INI functions on regular bases. | What does that mean? Both our functions are highly accessible and easy to understand. It's nothing like COM or xpath, a noob could use our scripts.
| majkinetor wrote: | | I don't think that such operation is common. | I believe it is. Do you notice a pattern in my list of functions? They can be grouped as create, move, delete and find for both keys and sections, save, load and convert. It's not as apparent to whether your library follows a similar scheme, which is why I digressed in the first place.
| majkinetor wrote: | | The difference in our viewpoints is only that you are thinking with database model in mind, while I don't. | You probably just read the title of this thread, gratz
| majkinetor wrote: | | As you see, our modules, like i told you, are very different. | ... and as I told you, I had not reviewed the changes you made after the 0.1 release. Now I see that it's different I think it's a great opportunity for users to pick whatever's right for them (and the dl stats are very telling here). _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3624 Location: Belgrade
|
Posted: Wed Dec 19, 2007 11:25 pm Post subject: |
|
|
| Quote: | | What does that mean? |
That means that I can't use your functions on strings, unless I save them in file previously, which was the point of INI module in the first place.
| Quote: | | Now I see that it's different I think it's a great opportunity for users to pick whatever's right for them |
Indeed
| Quote: | | (and the dl stats are very telling here). |
can I have your scaned autogram please ?  _________________
 |
|
| Back to top |
|
 |
Titan
Joined: 11 Aug 2004 Posts: 5049 Location: imaginationland
|
Posted: Wed Dec 19, 2007 11:49 pm Post subject: |
|
|
| majkinetor wrote: | | That means that I can't use your functions on strings, unless I save them in file previously, which was the point of INI module in the first place. | You can now in v1.08
The save function has always been able to update existing INI structures, retaining formatting, comments etc. That's another feature that these modules should have, but which afaik. yours lacks. _________________
RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2") |
|
| Back to top |
|
 |
Wouther
Joined: 01 May 2007 Posts: 78 Location: The Netherlands
|
Posted: Fri Jul 11, 2008 4:48 pm Post subject: |
|
|
Hello, I found a bug!
I couldn't save any changes using ini_Save() and took a look at your code.
These are the lines 491 and 492, at the end of the ini_Save() function.
| Code: | FileDelete, %file%
FileAppend, %d%, %file% | The variable file doesn't exist! I searched the rest of the code and it turns out this is the only time you use this variable. It is never changed or even declared! The user does enter the filename in the function - as the second parameter - but for some reason you change the contents/purpose of the variable/parameter src from the filename to the contents of the file.
One way to fix this is, obviously, saving the variable src at the very beginning of the function, like this:
That did the trick for me.  _________________ Printing css/html-formatted text |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|