|
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)
|
|
|
|
|
capital H wrote: Seems to be missing in 6.3.a7 Yes it does, although there is a dropdown field too (but with only one option).
6.3.a8 UNICODE/ANSI is the first build of ToDOList that is working with UNICODE and ANSI lists, if I'm not mistaken.
capital H wrote: interaction with dialog boxes are finicky at best
I did it with AHK like this:
SendInput, {Altdown}{Altup}f ; it's not meant as {Altdown}f{Altup}
; I want to exclude problems with the editing controls.
SendInput, a
SendInput, {tab}
SendInput, u
SendInput, {Enter}
Works for me. Has to, since I'm not an AHK - Guru
|
|
|
|
|
I only ran it for 4500 tasks
Opening TDL+Opening tasklist is more or less equal
Saving ±5 times slower for unicode
Sorting about 50% slower for unicode (this is very surprising for me)
I am also surprised that first open is almost equal to second open time, as the tasklist that I create is very basic and ToDoList.exe needs to create a lot of new information. I guess the smaller filesize makes up for it though.
My recommendation is that optimisation (if required) should focus on the saving part. The increased filesize should increase save time by at most a factor of x2, the x5 factor must then be a result of the codepage conversions. Also saving time is more important for me than opening time, as it happens many times more.
Benchmark 4500 tasks ANSI Unicode
Opening TDL: 0.750000 0.812000
Opening TaskList: 35.766000 34.312000
Saving TaskList: 5.141000 25.188000
Sorting (10 loops): 4.265000 6.485000
Re-opening TaskList: 36.297000 36.547000
Re-saving TaskList: 5.094000 28.453000
Total time to run benchmarks: 236.437000
|
|
|
|
|
capital H wrote: My recommendation is that optimisation (if required) should focus on the saving part. I hear you, but I feel that I also need to look at the bigger picture so that whatever changes are made are not just quick-fixes.
|
|
|
|
|
Feature Request 1: Paste from text
Upon activation (menu item or shortcut) TDL will analyze the clipboard, and if in exactly the same format as the "copy as text" - paste each line of the clipboard contents as new tasks. This will allow users to create new tasks in Autohotkey.
Feature Request 2: Paste to Replace
Upon activation (menu item or shortcut) TDL will analyze the clipboard, and if in exactly the same format as the "copy as text" - replace the matching tasks of the active tasklists with the clipboard contents. This will allow users to modify existing tasks in Autohotkey.
I know there is a lot of moving parts at the moment, so I do not expect this soon, if at all.
H
|
|
|
|
|
capital H wrote: Feature Request 1: Paste from text
I found something in the autohotkey forum months ago. Maybe this helps a little.
http://www.autohotkey.com/forum/topic8320.html[^]
Written by ..dB.. (doublebogey) ages ago.
Cheers,
Jochen
|
|
|
|
|
Thanks
This should solve my current problem, but longer term I would want something in line with the above.
He uses the command line option to add tasks (which strangely I forgot about) however it has the limitations:
1) You can only set task title and comments (no due date etc)
2) You cannot modify a task
|
|
|
|
|
capital H wrote: This should solve my current problem Great.
capital H wrote: it has the limitations:
1) You can only set task title and comments (no due date etc)
2) You cannot modify a task
I have a script (it's a big help for me) that uses the command line parameters of ToDoList to create a new task (with an optional text for 'the comments field)', but this shows the limitations of the ToDoList command line parameters, since I have to add 'due date' etc. later.
It would be great if ToDoList could provide more of these parameters (for each and every 'editing control'). Then it would be possible too, to write a script that gives the user the chance to put in all the infos (allocated to, due date, start date ...) he needs for a specific task at the very moment he creates it. [Maybe such an option should be a standard part of ToDoList?]
The option to modify a task would be more difficult I think:
Three ideas:
a) there is a command line parameter that asks for the task ID of the task that should be modified
b) if the users doesn't know the ID the script offers to browse through a tasklist
c) the selected Task in a specific list will be changed.
Tough ...
|
|
|
|
|
TCP_JM wrote: The option to modify a task would be more difficult I think:
Three ideas:
a) there is a command line parameter that asks for the task ID of the task that should be modified
b) if the users doesn't know the ID the script offers to browse through a tasklist
c) the selected Task in a specific list will be changed.
I would prefer a paste from clipboard solution, one can prepare the clipboard in advance (possibly from a task you copied from TDL) and just paste the modified task back.
|
|
|
|
|
capital H wrote: I would prefer a paste from clipboard solution, one can prepare the clipboard in advance (possibly from a task you copied from TDL) and just paste the modified task back.
Your suggestion shows that you are a lot more experienced with programming and developing software/scripts. I have no idea how to work in/on the clipboard like in a text file (delete things, add things to the content the clipboard already has without deleting the rest etc.).
|
|
|
|
|
Funny how old things pop up now and again.
I have my own brain dump on this adding tasks idea.
Direct editing of the raw file should be a strict 'never'.
but a semi automated import function could be helpful
If TDL monitored a predefined external folder for files in the tdl-xml format, and popped up a option to import into a List when TDL detects a new file.
This would allow others to write plugin style converters for email/clipboard/AHK/etc etc.
I think Dan even talked of a command line switch that would import a tdl file, but I could not find it.
Currently I am on holidays, but will contribute more when I return
..dB..
Everyone makes mistakes, that's why they put erasers on pencils.
Milhouse, The Simpsons.
|
|
|
|
|
..dB.. wrote: Direct editing of the raw file should be a strict 'never'.
I cannot agree more. I read in directly from the Tasklist - but I do not touch it for output.
..dB.. wrote: If TDL monitored a predefined external folder for files in the tdl-xml format, and popped up a option to import into a List when TDL detects a new file.
I would still prefer an option to import/modify without any user intervention.
|
|
|
|
|
..dB.. wrote: Funny how old things pop up now and again. The 'WWW' doesn't forget. This time: good for us.
..dB.. wrote: Currently I am on holidays,
Lucky you...
..dB.. wrote: but will contribute more when I return Highly appreciated.
Jochen
|
|
|
|
|
See my comments here[^].
It is not my intention (or desire) to make TDL totally scriptable. That would skew it away from average users towards power-users and that is not preferable to me.
And that is my final word on the subject, sorry.
|
|
|
|
|
This question refers to the daily work with ToDoList on the one hand and the use of Autohotkey on the other.
1.) Daily work:
I'd like to have shortcuts (that maybe should only work if the comments field is visible and activated) shortcuts that:
* switch on/off the ruler, 'formatting toolbar', 'word wrap' (most important !!!)
* inserts a file link
* that opens the context menu of the 'comments field' with all the options mentioned above
Can't find a way to do that in the Preferences.
2.) Autohotkey
a) How can I "read out" the information whether e.g. 'word wrap' is activated, or not?
b) How can I address the command "word wrap"?
What I want to achieve is this:
if word wrap is activated
deactivate it.
else
do nothing.
[...different commands ...]
if word wrap is deactivated
activate it.
else
do nothing.
I know that "else..do nothing" ist not necessary. I just mentioned it to explain what I want to achieve.
Thank you very much in advance for your help.
Cheers,
Jochen
|
|
|
|
|
Funny you should post this, since I am working on something very similar: a customisable context menu in AHK which would combine user functions (i.e. AHK functions) and TDL functions. Unfortunately it is not nearly ready to share, but will post as soon as it is.
TCP_JM wrote: 1.) Daily work:
I'd like to have shortcuts (that maybe should only work if the comments field is visible and activated) shortcuts that:
* switch on/off the ruler, 'formatting toolbar', 'word wrap' (most important !!!)
* inserts a file link
* that opens the context menu of the 'comments field' with all the options mentioned above
On the context menu or as keyboard shortcuts?
In theory the following should work to toggle word wrap:
SetTitleMatchMode,2
#IfWinActive, AbstractSpoon
F6::
SendMessage, 0x111, 33068 ;fails
;SendMessage, 0x111, 33068,,RICHEDIT50W1, AbstractSpoon ;Try sending directly to the comment control - also fails
return
However it is not working for me.
(Ruler should be 32777 and toolbar 32776 - replace 33068 with these numbers)
It is not necessary to detect the current state - as these commands should toggle the state.
|
|
|
|
|
Thank you H (?),
I tried something like the code you mentioned above (based on the code you provided me with the other day) but it didn't work for me either.
capital H wrote: It is not necessary to detect the current state - as these commands should toggle the state.
I have to detect the current state. That's absolutely necessary.
Reason:
I want to paste a very long link in the comments field (text only) and it is necessary that this link will be displayed (only for a short time) in one single row.
If the AHK script toggles it can happen (and will happen) that ToDoList changes the 'word wrap' state from 'off' to 'on'. And as a result of that the very lonk link will be shown in two, three, four rows depending on the size of the 'comments field'.
One solution at the moment is to maximize the comments field. Most of the times it's not important then whether word wrap is on or of because the screen will be big enough to display the link in one row.
But (such is life) there are links who are a lot longer (or smaller screens regarding netbooks) and then the script fails.
You wrote: "Funny you should post this, since I am working on something very similar".
Yes it seems so.
My problem is that the clipboard contains two lines. The first one contains infos about the link, the second one the link itself.
I need to get rid of the first line, so I have to tell ToDoList to delete the first line and therefore ToDoList has to move the cursor to the right place, select the text and delete the text and the line.
Well it's easy if you only have two rows, but if you never know (depending on the size of the 'comments field') in how many rows ToDoList displays the two lines ... it's only possible if the script pastes the two lines at position {home}, but not if the cursor should stay where it is = somewhere in the 'comments field' according to the user's choice.
BTW 1:
The toggle commands are useful but the toggle commands should only be one option.
It's important to have a command for each and every view or control that allows the user to address the view or control directly.
BTW 2:
Do you know a command in AHK that makes sure that the screen the user sees the very minute he starts the script will be displayed as long as the script runs and then (at the end of the script) presents the new informations on the screen that are a result of the commands in the script?
At the moment the screen flickers or shows the result of every single command of AHK on the screen.
It would be a more elegant solution if the user sees only the screnn at the beginning and at the end. Couldn't find a solution for that in the AHK-CHM-file, nor in the AHK forum, nor in the www.
Thanks in advance.
|
|
|
|
|
TCP_JM wrote: My problem is that the clipboard contains two lines. The first one contains infos about the link, the second one the link itself.
I need to get rid of the first line, so I have to tell ToDoList to delete the first line and therefore ToDoList has to move the cursor to the right place, select the text and delete the text and the line.
Well it's easy if you only have two rows, but if you never know (depending on the size of the 'comments field') in how many rows ToDoList displays the two lines ... it's only possible if the script pastes the two lines at position {home}, but not if the cursor should stay where it is = somewhere in the 'comments field' according to the user's choice.
Can you parse the text in AHK, and only paste the second line? This should be easier and probably more reliable since you do note rely on keyboard instructions.
P.S.
For the Toolbar check if the ToolbarWindow32X is visible - then you know the toolbar is shown (x=tasklist number +1)
For the Ruler check if the AfxWbd42Y is visible - then you know the ruler is shown (Y=tasklist number *2+1)
Not that the above helps at the moment, since we cannot get the Send/postmessage to work.
I major workaround may be getting the wordwrap value from the INI file
[FileStates\tasklist.tdl\PLAIN_TEXT]
WordWrap=1
[FileStates\tasklist.tdl\some long string of seemingly random information - I did not know if it contained private data]
ShowRuler=1
ShowToolbar=1
WordWrap=0
But this is only valid if the ini file is saved (I have no idea when the tasklist is saved)
Another workaround may be to do an imagesearch for the wordwrap icon (this will only work if the toolbar is shown) but if the toolbar is not show or the style changes this method will fail.
TCP_JM wrote: Do you know a command in AHK that makes sure that the screen the user sees the very minute he starts the script will be displayed as long as the script runs and then (at the end of the script) presents the new informations on the screen that are a result of the commands in the script?
At the moment the screen flickers or shows the result of every single command of AHK on the screen.
It would be a more elegant solution if the user sees only the screnn at the beginning and at the end. Couldn't find a solution for that in the AHK-CHM-file, nor in the AHK forum, nor in the www.
I wish I did. I know how to detect if a redraw of the screen is starting, however I cannot prevent it (and the reactivate it when done). Essentially you have to use a shell hook to intercept - but I have no idea how to prevent TDL from execution as well.
|
|
|
|
|
Thank you very, very much.
I have to digest your informations first.
With infos like "AfxWbd42Y" my 'little grey cells' are in danger to overheat since I just started to use AHK and the times when they taught me a little 'Turbo Pascal' at the univerity (I never studied something related to IT) are lightyears ago ...
capital H wrote: Can you parse the text in AHK, and only paste the second line? It would be great if that's possible...I'll look into that.
Another idea I had was to use a very small programm which has no word wrap at all or use a small little prgramm where I can change the current state of 'word wrap' easily. But to do it ouside of AHK or ToDoList can only be a less-than-ideal solution.
I like the challenge of finding solutions for problems, like to find workarounds, but in some regards like this one the easiest solution still would be to have direct command like "deactivate word wrap', 'activate word wrap' and 'toggle word wrap' in ToDoList. It's a pity that ToDoList doesn't have that. Although the "if wintitle ... then ... else" workaround often works I'd appreciate it if ToDoList gets commands like 'activate Task Tree View' or activate List View' or 'activate comments field' and last but not least 'activate Tasks' in addition to toggle...
capital H wrote: But this is only valid if the ini file is saved (I have no idea when the tasklist is saved) I assume ToDoList can be easily told to save the list before getting the wordwrap value from the INI file and in between a litte "sleep, 1000".
capital H wrote: I wish I did. I know how to detect if a redraw of the screen is starting, however I cannot prevent it (and the reactivate it when done). Essentially you have to use a shell hook to intercept - but I have no idea how to prevent TDL from execution as well. Thanks. Although I was hoping that there is a solution: your answer is reassuring that there is probably no solution for this "problem" and it's not just me.
An idea came to my mind (even if I do not have the foggiest how to do that at the moment):
I was thinking about a screenshot that is taken at the beginnig of the script and displayed during the script works and then replaced by the real screen at the end.
|
|
|
|
|