Thanks for pointing to the Thor option.
Well, OK, one of the detail reasons, why I stopped working on parsing code to add mdots is, because of corner cases, where you can't tell, if a field is meant or a variable. It's easy to parse for LOCAL variable definitions and add m., it's just a search&replace, you can also easily avoid the var=expression case, but you never know, if a name you encounter not declared LOCAL is a private variable or a field name. Now you can say don't use private variables, but they accelerate recursive operations far more, than mdot, because you don't need to pass private variables on and you don't have an indirectly declared variable by lparameters on each recursion level.
And if you care about the last bit of percentages on performance, then also use STORE instead of = as assign operator.
Here's what I measured:
empty loop, 10 million iterations: 0.691 seconds
loop with 20 = assignments per iteration, 10 million iterations: 51.897 seconds
loop with 20 store assignments per iteration, 10 million iterations: 39.827 seconds
corrected loop body durations:
loop with 20 = assignments per iteration, 10 million iterations: 51.897 seconds - 0.691 seconds = 51.206 seconds
loop with 20 store assignments per iteration, 10 million iterations: 39.827 seconds - 0.691 seconds = 39.130 seconds
And that means store needs 39.130/51.206 = ca. 0.76 of the time of = assignment or = assignment takes 51.206/39.130 = ca 1.31 of STORE assignment.
But I also see no code samples making extensive use of STORE, it's like mdot, neglectable for the single assignment, but not in a tight loop.
Tamar has the only real valid point in my eyes, not knowing what names come from outside, that can bite you, I already gave a solution to that, introduce obfuscation, which for example means changing all your variable names to lengthy random strings, that won't crash with field names, it's quite easy introducing some defines, eg #DEFINE loRange djksd344hfjkdhdjkshfjsdfhsd5454khfjk234dsjkfsdj5623kfjhsdfhkdshf, for example, now the field name to make such a case of matching names would need a table with a djksd344hfjkdhdjkshfjsdfhsd5454khfjk234dsjkfsdj5623kfjhsdfhkdshf field. Besides that define, your code still has the loRange variable name and you can read it just normal.
In case you also need to address a field name lOrange, if you know that in advance, you avoid loRange as variable name, if you work on any other developers database with generic tools, like eg gendbc you read file names via AFIELDS for example, and then have names read in at runtime, use them with macro substitution, and they won't be redefined by #DEFINE. Also, defines don't change strings, eg you can have code like lcField = "lOrange", then &lcField and this stays lOrange, despite of the #DEFINE.
My and Tamar's experiences about how many times a random match of field and variable names occurred, differ very much, which may just be, because I have more control about my environment in terms of tables, naming convention and also table widths, in regard of the performance degradation being low. If you're at the point you can quench the last bit of acceleration out of mdot, you should perhaps go to other programming languages. The advantage of VFP is not performance but rapid development and easier maintenance, shorter code because of less atomic single commands, VFP really is a high level language in the data centric domain, which is it's main advantage. But in fact it's object code much compares to java p-code and is therefore not compiled for a cpu, but read by the runtime and thus VFP is an interpreter. If you want performance go C++, but for a weighed optimum of rapid develop and fast performance SQL Server and DotNet are the defacto standard for Windows, not VFP anymore.
Bye, Olaf.