Benchmarking Techniques, dynamic/runtime code generation

Mr. SenseTalk and I were talking this evening about what he considered a rather wordy and less than obvious means I use to check for an empty line. Since I can remember I have used

repeat with each line in aContainer by reference
 if words 1 to -1 of it are empty then delete it
end if

Mr. SenseTalk said why not try

if it is all whitespace then delete it

I liked how his version read, and tried it. Worked pretty well, except when a line is empty (when a container is empty, it also has one make believe empty line). So this approach would have to be modified to read

if it is all whitespace or it is empty then delete it

Still read ok, so decided to go with it. Then the idea of testing the many approaches that folks might be use. Mr. SenseTalk and I brainstormed for a bit, and came up with a list of possibilities (not exhaustive, add your own and try).

if word 1 to -1 of it is empty then delete it
if it is all whitespace then delete it
if it is empty or it is all whitespace then delete it
if it is all whitespace or it is empty then delete it
if it is empty or if it is all whitespace then delete it
if it is all whitespace or if it is empty then delete it
if number of words in it is zero then delete it
if number of words in it is less than one then delete it

A little indirect, I first built a loop that would test one of the lines of code…

-- Testing:  if word 1 of it is empty then delete it
set text to urlText
set sTime to now
repeat with each line in text by reference
 if word 1 of it is empty then delete it
end repeat
put "Execution Time (" & now - sTime & "): " & \
  "if word 1 of it is empty then delete it"

which I quickly stuffed into a container to be used with the merge function.

-- Testing:  [[command]]
set text to urlText
set sTime to now
repeat with each line in text by reference
[[command]]
end repeat
put "Execution Time (" & now - sTime & "): " & "[[command]]"

which finally was used as a container within the repeat loop that stuffs a new line of script to be used for each timing repeat loop.

repeat with each line command in commands
  put merge(form) & return after it
end repeat

Take a look at what is going on, and give a bit of time to sink in… What we are doing is dynamic code generation, with variables being slipped in during generation while finally executing the entire lot of stuff. In our case this stuff is a benchmarking test.

And finally, you will notice on the output of this set of tests, Mr. SenseTalk’s approach was far and beyond the fastest in all tests. In some cases by a factor of five.

Sun, 6/15/08 10:21:04 PM	START		Running Benchmarking.script
Execution Time (11.559514): if word 1 of it is empty then delete it
Execution Time (12.59106): if word 1 to -1 of it is empty then delete it
Execution Time (2.826471): if it is all whitespace then delete it
Execution Time (8.204797): if it is empty or it is all whitespace then delete it
Execution Time (7.683346): if it is all whitespace or it is empty then delete it
Execution Time (9.050291): if it is empty or if it is all whitespace then delete it
Execution Time (8.573515): if it is all whitespace or if it is empty then delete it
Execution Time (15.147024): if number of words in it is zero then delete it
Execution Time (10.283261): if number of words in it is less than one then delete it
Sun, 6/15/08 10:22:30 PM	SUCCESS		Execution Time 0:01:26 Benchmarking.script

If you have something your using for timing and benchmarking, please share with me here and talk about what you found out.