Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-04

Float to string conversion performance

4 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Max Nazhalov

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.

Reply by email

Max Nazhalov

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.

Reply by email

Florian Klaempfl
to Max Nazhalov
Max Nazhalov wrote
Anyway, I ran that diff on the same conditions as above. Full test suite did not show any regressions.

This is already a good sign.

Show quoted text 10 lines
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?

I guess nobody can competely oversee such changes to real2str so what about creating automatically a test program which converts a lot of random bit patters into strings by str(...) and compare the output of the old and new algorithm?

Reply by email

C Western
to Florian Klaempfl
Florian Klaempfl wrote 22 lines
Am 15.04.2012 17:03, schrieb Max Nazhalov: > > Anyway, I ran that diff on the same conditions as above. Full test > suite did not show any regressions. This is already a good sign. > 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? I guess nobody can competely oversee such changes to real2str so what about creating automatically a test program which converts a lot of random bit patters into strings by str(...) and compare the output of the old and new algorithm?

I think it tests a different code path, but the tests submitted as part of <http://bugs.freepascal.org/view.php?id=16907> might give you some ideas, as these picked out some specific numbers that were causing problems.

Colin

Reply by email