Ok, @dodicat got me started down the rabbit-hole of floating point double to string conversion performance in my original post @:
viewtopic.php?t=31450
Here's a slightly modified version of @dodicat's test code from:
viewtopic.php?p=289648#p289648
dodicat's C-lib snprintf(dbl)-to-zstring shows an average 28% better performance than native FB str(dbl)-to-string.
But dodicat was using 'dim as double d = 13.004' which hid a small detail related to snprintf()... snprintf(), (and all of the printf() family's variations when converting floating point values using the 'g' or 'G' specifier), has a default precision of only six (6) *significant* digits. Since dodicat's version used the default precision, snprintf() was not doing as much work as FB's str() and gave much better performance times.
After switching snprintf() to a floating point format string with 16 digits of precision, ("%.16g"), snprintf(dbl)-to-zstring only shows a 12% better performance than str(dbl)-to-string.
Also of note is that *all* of a double's characters impact the overall parsing performance of snprintf(). If the double is negative, the '-' character is additional overhead. The same thing if the double has an exponent; that 'E-004" adds a lot (relatively) of performance impact.
This shows that common use of str(dbl) is fine, but for critical performance, snprintf(dbl) is the one to choose - (just make sure to set the precision to meet your requirements).
'/
Code: Select all
#include "crt.bi"
const as integer ITERATIONS = 1000000
dim as zstring*24 sz
dim as string ss
dim as double d
dim as double t
RANDOMIZE , 3 ' Choose FreeBASIC Mersienne Twister RND() and seed it with a random seed value.
for j as integer = 1 to 2
if j = 1 then d = 0.5429259254597127
if j = 2 then d = -0.5429259254597127e-9
print
print str(d);" = Double to convert to String"
print
print "[Result]";tab(31);"[Time]";tab(60);"[Convert floating point Doubles to ZStrings / Strings]"
print
for k as integer = 1 to 2
t=timer
for n as long=1 to ITERATIONS
snprintf(@sz, 24, "%g", d)
next
print sz;tab(30);timer-t;tab(60);"Zstring = snprintf(DOUBLE) -- 6 digits"
t=timer
for n as long=1 to ITERATIONS
snprintf(@sz, 24, "%.16g", d)
next
print sz;tab(30);timer-t;tab(60);"Zstring = snprintf(DOUBLE) -- 16 digits"
t=timer
for n as long=1 to ITERATIONS
sz=str(d)
next
print sz;tab(30);timer-t;tab(60);"Zstring = STR(DOUBLE)"
t=timer
for n as long=1 to ITERATIONS
ss=str(d)
next
print ss;tab(30);timer-t;tab(60);"String = STR(DOUBLE)"
print
next k
next j
end
Code: Select all
0.5429259254597127 = Double to convert to String
[Result] [Time] [Convert floating point Doubles to ZStrings / Strings]
0.542926 0.347559200017713 Zstring = snprintf(DOUBLE) -- 6 digits
0.5429259254597127 0.4633024999639019 Zstring = snprintf(DOUBLE) -- 16 digits
0.5429259254597127 0.5621779999928549 Zstring = STR(DOUBLE)
0.5429259254597127 0.5508228000253439 String = STR(DOUBLE)
0.542926 0.3492437000386417 Zstring = snprintf(DOUBLE) -- 6 digits
0.5429259254597127 0.4629746000282466 Zstring = snprintf(DOUBLE) -- 16 digits
0.5429259254597127 0.5597476999973878 Zstring = STR(DOUBLE)
0.5429259254597127 0.5506630999734625 String = STR(DOUBLE)
-5.429259254597127e-010 = Double to convert to String
[Result] [Time] [Convert floating point Doubles to ZStrings / Strings]
-5.42926e-010 0.4747977999504656 Zstring = snprintf(DOUBLE) -- 6 digits
-5.429259254597127e-010 0.5822030999697745 Zstring = snprintf(DOUBLE) -- 16 digits
-5.429259254597127e-010 0.6784165999852121 Zstring = STR(DOUBLE)
-5.429259254597127e-010 0.6684604999609292 String = STR(DOUBLE)
-5.42926e-010 0.4798713000491262 Zstring = snprintf(DOUBLE) -- 6 digits
-5.429259254597127e-010 0.5838622000301257 Zstring = snprintf(DOUBLE) -- 16 digits
-5.429259254597127e-010 0.6792778999079019 Zstring = STR(DOUBLE)
-5.429259254597127e-010 0.6711904000258073 String = STR(DOUBLE)
CBruce