[fpc-devel] Float to string conversion performance

Max Nazhalov stein_nospam at mail.ru
Sun Apr 15 17:03:48 CEST 2012


Sorry, 1st post was eaten somewhere.. 

Float to string conversion is very slow when dealing with high-order numbers. Conversion time is almost linearly increases with exponent.

Test case [i386/Win32,"ValReal=extended"]: converting 1000000 numbers into default exponential format by "writeln(them)" to dev/nul.

"1.2345678901234568E+3999": FPC=79.72 seconds, Delphi=0.71 seconds
"1.2345678901234568E-3999": FPC=35.88 seconds, Delphi=0.67 seconds

Side note: negative exponents are handled by FPC about 2 times faster than positive ones.

The problem lies in float to string conversion routine str_real() [rtl/inc/real2str.inc].

Current implementation uses several loops of the form "while <not done> do d:=d*10" or equivalents, so the simple fix is not possible without significant procedure rework.

There is a non-invasive workaround to improve performance without making major changes in the algorithm itself -- an artificial reduction of the exponent before performing the conversion (see attached diff). But I'm not sure this will not introduce some artifacts in conversion.

Anyway, I ran that diff on the same conditions as above. Full test suite did not show any regressions. My test case resulted in:

"1.2345678901234568E+3999": FPC=1.92 seconds
"1.2345678901234568E-3999": FPC=1.83 seconds

so its timing is still about 2.5 times slower than Delphi, but much better then before.

Can anyone review or test suggested changes before creating Mantis entry?

In particular, I'm not sure what the last line of the patch is placed correctly ("inc(correct,high_exp10_reduced);"). Ideally this operation could be performed when "E.." is emitted, but there is another branch for "f<0" for fixed precision, which is hard to understand for me of how incorporate this additional exponent shift (possibly, it's too late to do something like this?..).

---
 WBR, Max.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: real2str.diff
Type: application/octet-stream
Size: 4669 bytes
Desc: not available
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20120415/3add3ed4/attachment.obj>


More information about the fpc-devel mailing list