Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
String performance problem and some odd results
Message
From
07/12/2001 19:24:46
 
 
To
All
General information
Forum:
Visual FoxPro
Category:
Other
Title:
String performance problem and some odd results
Miscellaneous
Thread ID:
00591569
Message ID:
00591569
Views:
53
This morning I was testing a module and it took over half a minute to complete a job that should have taken it only a fraction of a second (at first I thought Fox was hung or I had created an infinite loop somehow).

When I profiled the thingy I found that almost all of the time was spent in a couple hundred calls to EMPTY(), LEN(), or SUBSTR() which you would normally expect to complete in constant time. Thus I hacked a small test program, got some really peculiar results, and turned to more pressing matters. <g> But this evening I sat down to investigate and the test program grew to a handsome 300+ lines in the process (much of this comments, though) as I refined the test setup to remove possible flaws that might account for the strange findings.

The result is this: except for parameter passing by reference, all string manipulation in Fox takes time linear in the size of the string, including stuff like ASC(s), LEFT(s, 1) or LEN(s) that you would normally expect to take the same minuscule amount of time no matter how large the string.

The program has grown too big for inclusion in this post but I uploaded it as http://www.meow-labs.de/dl/big_string_bench.prg in case you want to check for yourself (I tested it on VFP3 and VFP7). You can also use the setup to run your own test statements like
do big_string_bench with "x = s + '?'"
Here is the result log (Pentium III/850, 256 MB RAM, NT5, VFP7). The first three tests were just for checking parameter passing (the positive result is that surrounding the string parameter with parens to force value passing does not incur a performance penalty when SET("UDFP") == "VALUE").
Visual FoxPro 07.00.0000.9297 for Windows
*
* 100 times:  x = UDF(@s)
*
pass  1, string size  1048576 -->         0,000 seconds
pass  2, string size  2097152 -->         0,010 seconds
pass  3, string size  4194304 -->         0,000 seconds
pass  4, string size  8388608 -->         0,010 seconds
*
* 100 times:  x = UDF(s)
*
pass  1, string size  1048576 -->         1,762 seconds
pass  2, string size  2097152 -->         4,417 seconds
pass  3, string size  4194304 -->         9,313 seconds
pass  4, string size  8388608 -->        19,078 seconds
*
* 100 times:  x = UDF((s))
*
pass  1, string size  1048576 -->         1,973 seconds
pass  2, string size  2097152 -->         4,416 seconds
pass  3, string size  4194304 -->         9,304 seconds
pass  4, string size  8388608 -->        18,526 seconds
*
* 100 times:  x = SUBSTR(s, 1 + &lt;random&gt;, 1)
*
pass  1, string size  1048576 -->         0,591 seconds
pass  2, string size  2097152 -->         1,181 seconds
pass  3, string size  4194304 -->         2,364 seconds
pass  4, string size  8388608 -->         4,717 seconds
*
* 100 times:  x = LEFT(s, 1)
*
pass  1, string size  1048576 -->         0,591 seconds
pass  2, string size  2097152 -->         1,182 seconds
pass  3, string size  4194304 -->         2,363 seconds
pass  4, string size  8388608 -->         4,717 seconds
*
* 100 times:  x = RIGHT(s, 1)
*
pass  1, string size  1048576 -->         0,591 seconds
pass  2, string size  2097152 -->         1,181 seconds
pass  3, string size  4194304 -->         2,364 seconds
pass  4, string size  8388608 -->         4,716 seconds
*
* 100 times:  x = LEN(s)
*
pass  1, string size  1048576 -->         0,751 seconds
pass  2, string size  2097152 -->         2,003 seconds
pass  3, string size  4194304 -->         4,486 seconds
pass  4, string size  8388608 -->         8,893 seconds
*
* 100 times:  x = EMPTY(s)
*
pass  1, string size  1048576 -->         0,771 seconds
pass  2, string size  2097152 -->         2,033 seconds
pass  3, string size  4194304 -->         4,536 seconds
pass  4, string size  8388608 -->         9,444 seconds
*
* 100 times:  x = ASC(s)
*
pass  1, string size  1048576 -->         0,761 seconds
pass  2, string size  2097152 -->         2,013 seconds
pass  3, string size  4194304 -->         4,486 seconds
pass  4, string size  8388608 -->         9,444 seconds
*
* 100 times:  x = iif(FSEEK(f, &lt;random&gt;) # 0 or .T., FREAD(f, 1), "")
*
* time includes writing the string to disk before the loop
pass  1, string size  1048576 -->         0,051 seconds
pass  2, string size  2097152 -->         0,110 seconds
pass  3, string size  4194304 -->         0,211 seconds
pass  4, string size  8388608 -->         0,932 seconds
*
* 100 times:  x = iif(FSEEK(f, &lt;random&gt;) # 0 or .T., FREAD(f, 1), "")
*
pass  1, string size  1048576 -->         0,000 seconds
pass  2, string size  2097152 -->         0,010 seconds
pass  3, string size  4194304 -->         0,000 seconds
pass  4, string size  8388608 -->         0,000 seconds
Next
Reply
Map
View

Click here to load this message in the networking platform