|
[modified: some multipliers were wrong]
Equivalent time multipliers relative to 6.2.7 loading/saving '500_Tasks.tdl' follow the results.
6.2.7 (Ansi)
Ansi build loading Ansi tasklists:
Loading '500_Tasks.tdl' took 2000 ms (1.00x)
Loading '1000_Tasks.tdl' took 5812 ms (1.45x)
Loading '1500_Tasks.tdl' took 11328 ms (1.89x)
Loading '2000_Tasks.tdl' took 17782 ms (2.22x)
Ansi build saving Ansi tasklists:
Saving '500_Tasks.tdl' took 297 ms (1.00x)
Saving '1000_Tasks.tdl' took 829 ms (1.39x 2.07x)
Saving '1500_Tasks.tdl' took 1891 ms (2.12x 3.15x)
Saving '2000_Tasks.tdl' took 3343 ms (2.81x 4.17x)
6.3.a8 (Ansi)
Ansi build loading Ansi tasklists:
Loading '500_Tasks.tdl' took 2156 ms (1.08x)
Loading '1000_Tasks.tdl' took 7813 ms (1.95x)
Loading '1500_Tasks.tdl' took 13984 ms (2.33x)
Loading '2000_Tasks.tdl' took 17156 ms (2.14x)
Ansi build saving Ansi tasklists:
Saving '500_Tasks.tdl' took 1094 ms (3.68x)
Saving '1000_Tasks.tdl' took 4313 ms (7.26x)
Saving '1500_Tasks.tdl' took 8781 ms (9.86x)
Saving '2000_Tasks.tdl' took 14093 ms (11.86x)
Ansi build loading Unicode tasklists:
Loading '500_TasksU.tdl' took 2953 ms (1.48x)
Loading '1000_TasksU.tdl' took 9390 ms (2.35x)
Loading '1500_TasksU.tdl' took 12297 ms (2.04x)
Loading '2000_TasksU.tdl' took 20625 ms (2.58x)
Ansi build saving Unicode tasklists:
Saving '500_TasksU.tdl' took 1250 ms (4.20x)
Saving '1000_TasksU.tdl' took 4453 ms (7.50x)
Saving '1500_TasksU.tdl' took 9437 ms (10.59x)
Saving '2000_TasksU.tdl' took 15343 ms (12.91x)
6.3.a8 (Unicode)
Unicode build loading Ansi tasklists:
Loading '500_Tasks.tdl' took 2047 ms (1.02x)
Loading '1000_Tasks.tdl' took 6734 ms (1.68x)
Loading '1500_Tasks.tdl' took 11797 ms (1.97x)
Loading '2000_Tasks.tdl' took 18156 ms (2.27x)
Unicode build saving Ansi tasklists:
Saving '500_Tasks.tdl' took 1047 ms (3.52x)
Saving '1000_Tasks.tdl' took 4000 ms (6.73x)
Saving '1500_Tasks.tdl' took 8907 ms (10.00x)
Saving '2000_Tasks.tdl' took 14656 ms (12.34x)
Unicode build loading Unicode tasklists:
Loading '500_TasksU.tdl' took 1860 ms (0.93x)
Loading '1000_TasksU.tdl' took 5922 ms (1.48x)
Loading '1500_TasksU.tdl' took 12204 ms (2.03x)
Loading '2000_TasksU.tdl' took 19031 ms (2.38x)
Unicode build saving Unicode tasklists:
Saving '500_TasksU.tdl' took 1188 ms (4.00x)
Saving '1000_TasksU.tdl' took 4140 ms (6.97x)
Saving '1500_TasksU.tdl' took 9234 ms (10.36x)
Saving '2000_TasksU.tdl' took 15656 ms (13.18x)
What these results appear to show
1. The relative performance of 6.2.7 loading degrades as the number of tasks increases, and presumably this trend would continue for larger tasklists (until it becomes unusable).
2. The relative performance of 6.2.7 saving also degrades as the number of tasks increases,
similarly to the loading but this time it's comparable to the number of tasks squared.
3. Both 6.3.a8 Ansi and 6.3.a8 Unicode have similar performances to 6.2.7 when loading tasklists of either Ansi or Unicode format.
4. Both 6.3.a8 Ansi and 6.3.a8 Unicode have much poorer performance compared to 6.2.7 and the trend as the number of tasks increases worsens.
What I need to do before 6.3 can be released
1. Investigate the reasons why both saving and loading performance degrades as the number of tasks increases across all versions and formats.
2. Investigate why loading is so much slower to saving in 6.2.7.
3. Investigate the reason why the save performance of 6.3.a8 is so much worse than 6.2.7 even in comparison the Ansi version of 6.3.a8 loading Ansi format tasklists (should be the same).
ps. I would appreciate someone running their eyes over my maths in case I've made an obvious mistake.
pps. Remember that the multipliers are all relative to 6.2.7 loading and saving the 500 task tasklist.
.dan.g.
AbstractSpoon Software
abstractspoon2_at_optusnet_dot_com_dot_au
modified on Sunday, July 31, 2011 8:57 PM
|
|
|
|
|
Using Sysinternals Process Explorer I observe that when saving TodoListX.exe (6.2.7 and 6.3.a8 ANSI only though):
1) Performs a lot of CPU intensive calculations (50% CPU usage - dual core) for most of the time it takes to save a file.
2) For a very short period of time (less than 0.5 seconds - the shortest update interval) writes to disk.
I can only guess at how the internals of TDL.exe works, but my guess is that most of the work is performed by taking the internal representation of the tasklist and transforming it into a MSXML ready object. I wrote a very simple loader in AHK, which loads a tasklist into an AHK object, and then just displays the tasklist in a treeview. My timings:
File read time: 31
XML Load time: 141
Object Create time: 1062
Gui Creation time: 235
Total load time: 1469 (sum of above)
Time to add 100 tasks: 0
Total Save time: 265
As you can see most of the time is spent in creating the object (which consists of traversing the XML tree, most of the time probably spent in the inner loop of capturing all the attributes). The add 100 tasks is done by directly inserting these tasks as top level tasks into the MSXML structure (adding child tasks would have been much slower). Saving is done by saving the MSXML structure directly (since I made changes to the structure directly - I do not have to convert my internal representation to a MSXML format) - and as you can see is pretty nippy.
Now, thinking about this, my guess is that the optimal structure might look something like this:
When loading a tasklist, traverse through the MSXML tree, and load the data directly to the GUI from the tree. At the same time, keep a list of pointers (accessed by the unique ID of each task) to each task in the MSXML structure.
When a task needs to be changed, use the list of pointers to get an O(1) lookup of where the task is located in the MSXML structure. Update the MSXML structure directly.
When saving, just call the MSXML.save instruction to save the structure to disk. Since the structure is up to date this should be extremely quick.
The consequences of such a change would probably be far reaching as you would have to change the way you interact with the tasklist in possibly many places.
PS: I cannot find in the source what version of MSXML you are using, but you can also try to use MSXML.6.0 if you are not using it already, it should be easy to change (unless you are using some of the legacy functions). This will change your system requirements to WinXp SP3 as a minimum though (I cannot find any system requirements on TDL anywhere (except some very old comments like ToDoList 6.2.8 - An effective and flexible way to keep on top of your tasks[^], so I do not know if this is a problem).
PPS. These comments are just that, comments, and is by no ways a request that you rewrite the entire inner workings of TDL.exe. Efficiency of algorithms is something that lies close to my heart, though my expertise is not in C++ or MSXML and I feel that I cannot really help you more, though I wish I could.
|
|
|
|
|
Thx for our suggestions, they will be invaluable in my efforts to code more optimally.
In my own search, I have managed to find a 4x speed improvement by re-coding how tasks are inserted into the tree control. I was still using an old algorithm which constructed the data structure and tree in one hit. Once I separated these processes I was able to work much more efficiently. So now a 2000 task file loads in 6 seconds. I would be very interested to see what times you get if you run your script on a similarly sized tasklist.
|
|
|
|
|
Specified file
File read time: 0 (it might have been in my file cache though - AHK timing is accurate to about 10ms)
XML Load time: 125
Object Create time: 656
Gui Creation time: 156
Total load time: 937
Total Save time: 78
UniCode save: 282 (much slower than ANSI)
Specified file - converted to unicode
File read time: 31
XML Load time: 94
Object Create time: 656
Gui Creation time: 141
Total load time: 922
Total Save time: 93
UniCode save: 328
Note that all timings are with the Unicode build of AHK
The code
#SingleInstance force
File=C:\2000_tasks.tdl
StartTime:=A_TickCount
StartTime2:=A_TickCount
FileRead, xml, %File%
result:="File read time:`t" . (A_TickCount -StartTime) . "`n"
StartTime:=A_TickCount
TDL:=loadXML(XML)
result.="XML Load time:`t" . (A_TickCount -StartTime) . "`n"
test:=TDL.childNodes.Item(0)
for attrib In test.attributes
if attrib.name="encoding"
{
attrib.nodevalue:="UTF-16" ;uncomment to use unicode in saving - currently I have no other workaround
}
StartTime:=A_TickCount
TaskList:=XML2Object(TDL.childnodes)
result.="Object Create time:`t" . (A_TickCount -StartTime) . "`n"
StartTime:=A_TickCount
Gui, Add, TreeView,gTreeviewHandler vTreeViewTasks w400 h500
AddTree(TaskList)
Gui, Show ; Show the window and its TreeView.
result.="Gui Creation time:`t" . (A_TickCount -StartTime) . "`n"
result.="Total load time:`t" . (A_TickCount -StartTime2) . "`n"
;StartTime:=A_TickCount
;AddTasks(TDL,100)
;result.="Add 100 tasks:`t" . (A_TickCount -StartTime) . "`n"
test:=TDL.childNodes.Item(0)
for attrib In test.attributes
if attrib.name="encoding"
{
attrib.nodevalue:="windows-1252" ;uncomment to use unicode in saving - currently I have no other workaround
}
StartTime:=A_TickCount
TDL.save("C:\Hercules\My Documents\Todolist\QA Ansi (Saved).tdl")
result.="Total Save time:`t" . (A_TickCount -StartTime) . "`n"
test:=TDL.childNodes.Item(0)
for attrib In test.attributes
if attrib.name="encoding"
{
attrib.nodevalue:="UTF-16" ;uncomment to use unicode in saving - currently I have no other workaround
}
StartTime:=A_TickCount
TDL.save("C:\Hercules\My Documents\Todolist\QA Uni (Saved).tdl")
result.="UniCode save:`t" . (A_TickCount -StartTime) . "`n"
ClipBoard:=Result
msgbox,%result%
exitapp
TreeviewHandler:
if (A_GuiControl="TreeViewTasks") and (A_GuiEvent="DoubleClick")
{
TaskID:=FindInTree(TaskLIst,A_EventInfo)
Gui, Destroy
tmp:="""" File """"
}
return
FindInTree(Tasklist,TVID)
{
enum:=TaskList._NewEnum()
while enum[ID, Task]
if isObject(Task)
{
if (Task.TVID=TVID)
return Task.ID
enum2:=Task._NewEnum()
while enum2[cID, Child]
if isObject(child)
{
GetID:=FindInTree(Task,TVID)
if (GetID<>"")
return GetID
}
}
return ""
}
XML2Object(nodes,level=0,parent="")
{
NewTasks:=Object()
for node in nodes
{
NodeName:=node.nodename
NodeO:=Object()
for attrib In node.attributes
NodeO[attrib.name]:=attrib.nodevalue
if (NodeName="Task")
NodeName:=NodeO.ID
if node.hasChildNodes
{
ChildNodes:=XML2Object(node.childNodes,level+1,nodename)
{
enum:=ChildNodes._NewEnum()
while enum[ID, Child]
{
NodeO[ID]:=Child
}
}
}
NewTasks[NodeName]:=NodeO
}
return NewTasks
}
loadXML(ByRef data)
{
o := ComObjCreate("MSXML2.DOMDocument.6.0")
o.async := false
o.loadXML(data)
return o
}
AddTasks(TaskList,numtasks=1)
{
Loop,%numtasks%
{
Random, TaskTitle , 0, 2147483647
Random, DueDate, 40000, 41000
TDL_Add_TopLevel(TaskList,TaskTitle,DueDate)
}
}
TDL_Add_TopLevel(TaskList,Title,DueDate="")
{
NextID:=TaskList.childNodes.Item(1).getAttribute("NEXTUNIQUEID")
MyNode:=TaskList.createNode(1,"Task","")
MyNode.setattribute("Title",Title)
Mynode.setattribute("ID",NextID)
MyNode.setattribute("DueDate",DueDate)
MyNode.setattribute("Magic","Added by TDL Benchmark")
TaskList.childNodes.Item(1).appendChild(myNode)
TaskList.childNodes.Item(1).setAttribute("NEXTUNIQUEID",NextId+1)
}
AddTree(Tasklist,Parent="")
{
enum:=TaskList._NewEnum()
while enum[ID, Task]
if isObject(Task)
{
if (Parent="")
{
if (ID ="TODOLIST")
NewP:=TV_Add(Task.Filename)
}
else
if task.title<>""
NewP:=TV_Add(Task.Title,Parent)
Task.TVID:=NewP
enum2:=Task._NewEnum()
HasChild=0
while enum2[cID, Child]
if isObject(child)
HasChild=1
if HasChild=1
AddTree(Task,NewP)
}
}
|
|
|
|
|
Interesting that you also experienced a substantial slow-down using Unicode. Anyway I hope to get to the bottom of it tonight.
|
|
|
|
|
I thought so too. At first I thought that it was due to the increased file size, since the MSXML object at that stage is fully prepared, and only needs to be dumped to a file (even the Unicode conversion is supposed to be done). The slowdown is much greater than x2 even, which is unexpected.
It is impossible to debug though since this happens in one call to MSXML - which is a black box for me.
|
|
|
|
|
|
Thanks Chris,
My conclusions:
Most optimisations seems to propose:
1)More CPUs
2)More threads
3)Smarter node selection
1 is not a solution for TDL, 2 possibly since multi-core processors is becoming more abundant, however the increased complexity of a multi-threaded solution is not a recommendation that I will make.
Smarter node selection for TDL is irrelevant as the whole tasklist needs to be loaded (it may be an option for AHK-based helper apps which may want to change only one task at a time - but this is not a consideration at the moment)
then http://www.hanselman.com/blog/AnOldieButAGoodieMSXMLAndFreeThreadedDomDocumentVsDomDocument.aspx[^] proposes
var doc = new ActiveXObject("MSXML2.DOMDocument");
doc.validateOnParse = false;
doc.resolveExternals = false;
doc.preserveWhiteSpace = false;
doc.load("somexml.xml");
which turns of some validation (I do not know what). I tested this and it led to an about 10% improvement - which is insufficient and does not address the nonlinearity problem of loading/saving.
http://www.xml.com/pub/a/2002/06/05/msxml4.html[^] proposes to use
objXML.setProperty("NewParser", true);
which apparently also turns of some validation, but my tests does not show any noticeable improvement.
This
http://msdn.microsoft.com/en-us/library/ms950760.aspx[^]
makes a few suggestions covered above, but also the statement:
"The fastest way to walk the tree is to avoid the children collection and any kind of array access. Instead, use firstChild and nextSibling:"
I currently use the children collection - so I will try and see what the speed improvement is (I read this article on my phone while travelling - but somehow I missed this part!)
It also highlights the slowdown in TDL with attribute heavy XML objects - which makes me wonder if an optimisation could be to not save defaults/blank strings (although this may cause a lot of overhead in the process as well - and it may not be easy to achieve)
Lastly: http://msdn.microsoft.com/en-us/magazine/cc163436.aspx[^]
I cannot test this, but this looks promising. Flexibility always adds overhead and a lot of the options in MSXML is not required by TDL
|
|
|
|
|
Hi,
regarding:
>>Smarter node selection for TDL is irrelevant as the whole tasklist needs to be loaded (it may be an option for AHK-based helper apps which may want to change only one task at a time - but this is not a consideration at the moment)<<
Would it make sense to use the sax parser instead of the DOM-Parser (msxml) as sax is working in serial manner?
http://msdn.microsoft.com/en-us/library/ms763715[^]
Regards
Chris
modified on Thursday, July 28, 2011 10:49 AM
|
|
|
|
|
I don't know if it might boost loading speeding - but SAX is for loading and not saving.
This will mean that you have a SAX loader and a DOM saver.
Biggest problem is in saving in any case, so I do not think switching the loading parser to SAX will add a lot of value.
|
|
|
|
|
capital H wrote: It also highlights the slowdown in TDL with attribute heavy XML objects - which makes me wonder if an optimisation could be to not save defaults/blank strings I like this idea. All it would mean would be to pass in a default value when building the DOM that when compared against would decide whether the attribute needed to be added. Even with text values, the most likely default value would be an empty string which is easy to test for efficiently.
|
|
|
|
|
I am stunned
From:
http://msdn.microsoft.com/en-us/library/ms950760.aspx[^]
"The number of Unicode characters in text content (including attribute values). Note that loading single-byte ANSI text into memory results in twice the number, because all text is stored as Unicode characters, which are two bytes each."
Now assuming this is true (written by "Chris Lovett is a program manager for Microsoft's XML team." - no reason to believe that it is not) I simply cannot understand the deterioration in unicode performance in both our implementations.
|
|
|
|
|
Something else that you can consider (although this will not help for speed) is to save the number of tasks in a tasklist in the TODOLIST line, and then to display some sort of progress indicator. At least then a user will know that todolist.exe is still working, and will know how long to wait (stretch you back/go and make coffee/go and have lunch)
|
|
|
|
|
|
Get it Here.
Changes
- 'Email Tasks' task selection improved
- Proper tdl file importer/exporter added with option to reset the task creation date
- Calendar plugin has new preferences dialog with improved display options
- Task selection history bug fixed
- Carriage return added between tasks exported/copied 'As Text'
- 'Your Language.csv' file added to 'Translations' sub-folder - ready for translation
Remember: This is still an Alpha build so backup your tasklists.
|
|
|
|
|
Hi Dan,
.dan.g. wrote: 'Email Tasks'
You can find this in previous versions too:
* Alt+F -> 'Email tasks ...'
* Right mouse click on a tab -> 'Send To ...'
* Right mouse click on a task in a tasklist -> an option to email or send a task is not offered.
(This is the context menu where I'd expect to find an "email task' option).
I'd like to suggest "email list / task' for all three, since it is possible to send a whole list too and not only selected tasks or a single task.
Cheers,
Jochen
|
|
|
|
|
Why don't I just route all the 'Send To...' commands (including right-clicking on selected Tasks) to the same selection dialog?
ie. When right-clicking on selected tasks it will initialize the 'Selection' radio button, else it selects 'All Tasks'.
|
|
|
|
|
.dan.g. wrote: Why don't I just route all the 'Send To...' commands (including right-clicking on selected Tasks) to the same selection dialog?
I'm not sure if I get you wright, but these two options
* Alt+F -> 'Email tasks ...'
* Right mouse click on a tab -> 'Send To ...'
are leading already to the same selection dialogue, aren't they?
Theoretically there are a lot of options like:
* right clicking on a single task -> leads to a context menu -> send task(s)
* selecting two and more tasks (but all the tasks in the list) -> same menu -> send task(s)
* selecting all the tasks -> send tasklist.
I think the context menu the user gets at the moment by clicking on a tab or using Alt+F is better, because it always offers all the options (send task, send list).
The only option that is missing is the 'send to...' when you right-click on a task.
And that should - as you mentioned - lead to the same context menu. Sure.
Last but not least:
I prefer "email task / list" instead of "send to" because it's more obvious than "send to".
"Send to" could have the meaning of "send to another list" or "send to printer", too. With "email tasks" it's WYSIWIG.
"Send to" would only be the right choice if you are planning to offer "send to another list" or "sending to printer". But still: I assume it would be better to have three items in the context menu instead of one item "send to" that leads to sub-menus.
|
|
|
|
|
I have been out of circulation for a while but finally completed my ANSI vs UNICODE AHK benchmarker.
Conclusion:
1. Opening TDL, opening a tasklist and most of the sorting seems to be at the same speed (A vs U)
2. Sorting by due date seems to be much slower for Unicode, but is still pretty quick.
3. There does not seem to be a difference for TDLU in opening a unicode file or an ANSI file (the first opening time benchmark is an ANSI file)
4. Saving tasklists is much slower for Unicode than for ANSI
The code:
UPDATED:
Longer delays between sending keystrokes
Sorting combined and looped to create more accurate timing
Nicer output
;http:
xml=
(
<?xml version="1.0" encoding="windows-1252"?>
<TODOLIST FILENAME="" PROJECTNAME="" FILEFORMAT="9" NEXTUNIQUEID="1" LASTMODIFIED="2011-07-21" FILEVERSION="640" EARLIESTDUEDATE="40745.00000000">
</TODOLIST>
)
while PathToTDLA=""
FileSelectFile,PathToTDLA,1,,Please select the path to the ANSI TODOLIST.exe,*.exe
while PathToTDLU=""
FileSelectFile,PathToTDLU,1,,Please select the path to the Unicode TODOLIST.exe, *.exe
if WinExist("AbstractSpoon")
{
MsgBox, Please close all ToDoList windows before running the benchmark
exitapp
}
setTitlematchMode,2
run, %PathToTDLA%
winwait, AbstractSpoon
SendMessage, 0x111, 32853,,,AbstractSpoon ; close all tasklists = which creates a new tasklist as well
sleep,500
winclose, AbstractSpoon
WinWaitClose
run, %PathToTDLU%
winwait, AbstractSpoon
SendMessage, 0x111, 32853,,,AbstractSpoon ; close all tasklists = which creates a new tasklist as well
sleep,500
winclose, AbstractSpoon
WinWaitClose
NumTasks:=4500
StartTime:=A_TickCount
loop,1
{
Result1:=benchmark(PathToTDLA,NumTasks)
Result2:=benchmark(PathToTDLU,NumTasks)
result.= "Benchmark " . NumTasks . " tasks `tANSI `t`t`tUnicode `n" . Combine(result1,Result2)
;Result.=benchmark(PathToTDLU,NumTasks,"UniCode")
NumTasks*=2
}
Result.="Total time to run benchmarks:`t" . (A_TickCount- StartTime)/1000 . "`n"
ClipBoard:=Result
Msgbox, Results in clipboard. Please paste in TDL forum
BenchMark(TDLExe,Num)
{
Random, , 1234 ;consistent random number generation - now everyone uses the same tasklists
StartTime := A_TickCount
global xml
TDL:=loadXML(XML)
AddTasks(TDL,Num)
TDL.save(A_Temp . "\BenchMark.tdl")
Result=
;Result.= "Creating tasklist (Debug info - not official benchmark): `t" . (A_TickCount- StartTime)/1000 . "`n"
StartTime := A_TickCount
run, %TDLExe%
winwait, AbstractSpoon
Result.= "Opening TDL: `t`t`t" . (A_TickCount- StartTime)/1000 . "`n"
SendMessage, 0x111, 33238 ,,,AbstractSpoon ;Task Tree View
StartTime := A_TickCount
run, %TDLExe% %A_Temp%\BenchMark.tdl
winwait, BenchMark
Result.= "Opening TaskList: `t`t" . (A_TickCount- StartTime)/1000 . "`n"
SendMessage, 0x111, 32798,,,AbstractSpoon ;Create new task
sleep,500
send {Enter}
sleep,500
send {del} ; and delete
sleep,500
StartTime := A_TickCount
SendMessage, 0x111, 32816,,,AbstractSpoon ;Save
winwait, BenchMark%A_Space%-
Result.= "Saving TaskList: `t`t" . (A_TickCount- StartTime)/1000 . "`n"
SendMessage, 0x111, 33151 ,,,AbstractSpoon ;unsorted
StartTime := A_TickCount
loop,10
{ SendMessage, 0x111, 33131 ,,,AbstractSpoon ;Sort by title
SendMessage, 0x111, 33151 ,,,AbstractSpoon ;unsorted
SendMessage, 0x111, 33128 ,,,AbstractSpoon ;Due date
}
Result.= "Sorting (10 loops): `t" . (A_TickCount- StartTime)/1000 . "`n"
StartTime := A_TickCount
SendMessage, 0x111, 32853,,,AbstractSpoon ; close all tasklists = which creates a new tasklist as well
winwait (untitled
StartTime := A_TickCount
SendMessage, 0x111, 57616,,,AbstractSpoon ; opens most recent open tasklist
winwait, BenchMark
Result.= "Re-opening TaskList: `t" . (A_TickCount- StartTime)/1000 . "`n"
SendMessage, 0x111, 32798,,,AbstractSpoon ;Create new task
sleep,500
send {Enter}
sleep,500
send {del} ; and delete
sleep,500
StartTime := A_TickCount
SendMessage, 0x111, 32816,,,AbstractSpoon ;Save
winwait, BenchMark%A_Space%-
Result.= "Re-saving TaskList: `t" . (A_TickCount- StartTime)/1000 . "`n"
SendMessage, 0x111, 32853,,,AbstractSpoon ; close all tasklists = which creates a new tasklist as well
sleep,500
winclose, AbstractSpoon
WinWaitClose
result.="`n"
return result
}
return
AddTasks(TaskList,numtasks=1)
{
Loop,%numtasks%
{
Random, TaskTitle , 0, 2147483647
Random, DueDate, 40000, 41000
TDL_Add_TopLevel(TaskList,TaskTitle,DueDate)
}
}
TDL_Add_TopLevel(TaskList,Title,DueDate="")
{
NextID:=TaskList.childNodes.Item(1).getAttribute("NEXTUNIQUEID")
MyNode:=TaskList.createNode(1,"Task","")
MyNode.setattribute("Title",Title)
Mynode.setattribute("ID",NextID)
MyNode.setattribute("DueDate",DueDate)
MyNode.setattribute("Magic","Added by TDL Benchmark")
TaskList.childNodes.Item(1).appendChild(myNode)
TaskList.childNodes.Item(1).setAttribute("NEXTUNIQUEID",NextId+1)
}
loadXML(ByRef data)
{
o := ComObjCreate("MSXML2.DOMDocument.6.0")
o.async := false
o.loadXML(data)
return o
}
Combine(String1, String2)
{
result=
Loop,parse, String2,`n
S%A_Index%:=substr(A_LoopField,instr(A_LoopField,"`t",false,-0))
Loop,parse, String1,`n
result.=A_LoopField . "`t" . S%A_Index% . "`n"
return result
}
modified on Friday, July 22, 2011 3:01 AM
|
|
|
|
|
Awesome, thanks _so_ much.
Hmm... Script causes 'Delete' confirmation dialog to pop up as well as 'Save' dialog, and when I respond to them it sort gets stuck and I have to kill ToDoList.exe.
Any thoughts?
ps. Despite this, thx for the benchmark results comparisons.
pps. Can you make the ini files available for download?
.dan.g.
AbstractSpoon Software
abstractspoon2_at_optusnet_dot_com_dot_au
modified on Thursday, July 21, 2011 8:35 PM
|
|
|
|
|
My script will get stuck as there is several places where it waits for the title to change etc. However I cannot understand why it will have the dialog popups for Delete and Save as I use the message IDs from Resource.h to communicate with ToDoList.exe. As long as the IDs between the build are the same, no "delete" or "Save" dialog should ever be displayed since I use:
Close all tasklists
Save Tasklist (not save as)
Open tasklist is done via command line
Create new task
Sort by title
sort by duedate
revert to unsorted
Open most recent tasklist
The only keyboard commands that I send is when I create a new task: I send an "Enter" and "Delete" (essentially I do this to force a changed file, I need a * in the title) - which can possibly be send to the wrong control, but I doubt it - I will change the code in any case to send to the treeview/listview.
ps. It is a pleasure.
pps. I do not follow, which INI files? My script does not make use of any INI files.
|
|
|
|
|
My own simple test for saving was:
1. 4500 tasks as Ansi in 6.2.7 (Ansi build) = 5 seconds
2. 4500 tasks as Ansi in 6.3.a8 (Unicode build) = 15 seconds
3. 4500 tasks as Unicode in 6.3.a8 (Unicode build) = 25+ seconds
I suspect that what's happening is that there's a lot of Ansi->Unicode->Ansi string conversions going on.
This will always cause a slowdown when 'Unicode to Ansi' saving(2), but I should be able to get the 'Unicode to Unicode' saving(3) to be as fast as the 'Ansi to Ansi' saving(1) notwithstanding a slight increase due to the increased Unicode file sizes.
|
|
|
|
|
I have heard that because most modern OSs is built on unicode and that unicode operations are hence quicker (obviously disk operations will be slower though).
PS: how do you choose in the UNICODE build what filetype to save as? My script just used a plain vanilla save, but I cannot find an option anywhere in ToDoListU.exe to choose the what to save it as.
modified on Friday, July 22, 2011 1:55 AM, to add PS
|
|
|
|
|
capital H wrote: I cannot find an option anywhere in ToDoListU.exe to choose the what to save it as. Try the menu: File / 'Save tasklist as', please.
On "the bottom" of the window you get you'll find a dropdown menu that offers:
'tasklist (*.tdl, *.xml)
and:
UNICODE tasklist (*.tdl, *.xml)
Hope this helps.
|
|
|
|
|
Found it.
Seems to be missing in 6.3.a7
I guess then my benchmark tests ANSI performance in the UNICODE build.
I will think how I can change it to UNICODE (which is not easy - interaction with dialog boxes are finicky at best)
|
|
|
|
|